blob: d4f0d059fb299c322c2158fadd49e9cbf9641dbd [file] [log] [blame]
/*
* 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.javaee.wildfly.ide;
import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.deploy.spi.DeploymentManager;
import org.netbeans.api.j2ee.core.Profile;
import org.netbeans.api.java.platform.JavaPlatform;
import org.netbeans.api.project.Project;
import org.netbeans.modules.j2ee.deployment.common.api.J2eeLibraryTypeProvider;
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule.Type;
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformFactory;
import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformImpl;
import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformImpl2;
import org.netbeans.modules.j2ee.deployment.plugins.spi.support.LookupProviderSupport;
import org.netbeans.modules.javaee.specs.support.api.JaxWs;
import org.netbeans.modules.javaee.specs.support.spi.JaxRsStackSupportImplementation;
import org.netbeans.modules.javaee.wildfly.WildflyDeploymentManager;
import org.netbeans.modules.javaee.wildfly.ide.ui.WildflyPluginUtils;
import org.netbeans.modules.javaee.wildfly.util.WildFlyProperties;
import org.netbeans.modules.websvc.wsstack.api.WSStack;
import org.netbeans.modules.websvc.wsstack.spi.WSStackFactory;
import org.netbeans.spi.project.libraries.LibraryImplementation;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.URLMapper;
import org.openide.modules.InstalledFileLocator;
import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
/**
*
* @author Kirill Sorokin <Kirill.Sorokin@Sun.COM>
*/
public class WildflyJ2eePlatformFactory extends J2eePlatformFactory {
static final String HIBERNATE_JPA_PROVIDER = "org.hibernate.ejb.HibernatePersistence";
static final String TOPLINK_JPA_PROVIDER = "oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider";
static final String KODO_JPA_PROVIDER = "kodo.persistence.PersistenceProviderImpl";
private static final WeakHashMap<InstanceProperties, J2eePlatformImplImpl> instanceCache = new WeakHashMap<InstanceProperties, J2eePlatformImplImpl>();
@Override
public synchronized J2eePlatformImpl getJ2eePlatformImpl(DeploymentManager dm) {
WildflyDeploymentManager manager = (WildflyDeploymentManager) dm;
InstanceProperties ip = manager.getInstanceProperties();
if (ip == null) {
throw new RuntimeException("Cannot create J2eePlatformImpl instance for " + manager.getUrl()); // NOI18N
}
J2eePlatformImplImpl platform = instanceCache.get(ip);
if (platform == null) {
platform = new J2eePlatformImplImpl(manager.getProperties());
instanceCache.put(ip, platform);
}
return platform;
}
public static class J2eePlatformImplImpl extends J2eePlatformImpl2 {
private static final Set<Type> MODULE_TYPES = new HashSet<Type>();
static {
MODULE_TYPES.add(Type.EAR);
MODULE_TYPES.add(Type.WAR);
MODULE_TYPES.add(Type.EJB);
MODULE_TYPES.add(Type.RAR);
MODULE_TYPES.add(Type.CAR);
}
private static final Set<Profile> WILDFLY_PROFILES = new HashSet<Profile>();
static {
WILDFLY_PROFILES.add(Profile.JAVA_EE_6_WEB);
WILDFLY_PROFILES.add(Profile.JAVA_EE_6_FULL);
WILDFLY_PROFILES.add(Profile.JAVA_EE_7_WEB);
WILDFLY_PROFILES.add(Profile.JAVA_EE_7_FULL);
WILDFLY_PROFILES.add(Profile.JAVA_EE_8_WEB);
WILDFLY_PROFILES.add(Profile.JAVA_EE_8_FULL);
WILDFLY_PROFILES.add(Profile.JAKARTA_EE_8_FULL);
}
private static final Set<Profile> JAKARTAEE_FULL_PROFILES = new HashSet<Profile>();
static {
JAKARTAEE_FULL_PROFILES.add(Profile.JAKARTA_EE_9_FULL);
JAKARTAEE_FULL_PROFILES.add(Profile.JAKARTA_EE_9_1_FULL);
JAKARTAEE_FULL_PROFILES.add(Profile.JAKARTA_EE_10_FULL);
}
private static final Set<Profile> EAP6_PROFILES = new HashSet<Profile>();
static {
EAP6_PROFILES.add(Profile.JAVA_EE_6_WEB);
EAP6_PROFILES.add(Profile.JAVA_EE_6_FULL);
}
private static final Set<Profile> WILDFLY_WEB_PROFILES = new HashSet<Profile>();
static {
WILDFLY_WEB_PROFILES.add(Profile.JAVA_EE_6_WEB);
WILDFLY_WEB_PROFILES.add(Profile.JAVA_EE_7_WEB);
WILDFLY_WEB_PROFILES.add(Profile.JAVA_EE_8_WEB);
WILDFLY_WEB_PROFILES.add(Profile.JAKARTA_EE_8_WEB);
WILDFLY_WEB_PROFILES.add(Profile.JAKARTA_EE_9_WEB);
WILDFLY_WEB_PROFILES.add(Profile.JAKARTA_EE_9_1_WEB);
WILDFLY_WEB_PROFILES.add(Profile.JAKARTA_EE_10_WEB);
}
private static final Set<Profile> JAKARTAEE_WEB_PROFILES = new HashSet<Profile>();
static {
JAKARTAEE_WEB_PROFILES.add(Profile.JAKARTA_EE_9_WEB);
JAKARTAEE_WEB_PROFILES.add(Profile.JAKARTA_EE_9_1_WEB);
JAKARTAEE_WEB_PROFILES.add(Profile.JAKARTA_EE_10_WEB);
}
private LibraryImplementation[] libraries;
private final WildFlyProperties properties;
public J2eePlatformImplImpl(WildFlyProperties properties) {
this.properties = properties;
}
@Override
public Set<org.netbeans.api.j2ee.core.Profile> getSupportedProfiles() {
if (this.properties.isWildfly()) {
if (this.properties.isServletOnly()) {
if (this.properties.getServerVersion().compareToIgnoreUpdate(WildflyPluginUtils.WILDFLY_27_0_0) >= 0) {
return Collections.unmodifiableSet(JAKARTAEE_WEB_PROFILES);
}
return Collections.unmodifiableSet(WILDFLY_WEB_PROFILES);
}
if (this.properties.getServerVersion().compareToIgnoreUpdate(WildflyPluginUtils.WILDFLY_27_0_0) >= 0) {
Set<org.netbeans.api.j2ee.core.Profile> allJakarta = new HashSet<>(
(int) Math.ceil((JAKARTAEE_FULL_PROFILES.size()+JAKARTAEE_WEB_PROFILES.size()) / 0.75));
allJakarta.addAll(JAKARTAEE_FULL_PROFILES);
allJakarta.addAll(JAKARTAEE_WEB_PROFILES);
return Collections.unmodifiableSet(allJakarta);
}
return Collections.unmodifiableSet(WILDFLY_PROFILES);
}
if (this.properties.getServerVersion().compareToIgnoreUpdate(WildflyPluginUtils.EAP_7_0) >= 0) {
return Collections.unmodifiableSet(WILDFLY_PROFILES);
}
return Collections.unmodifiableSet(EAP6_PROFILES);
}
@Override
public Set<org.netbeans.api.j2ee.core.Profile> getSupportedProfiles(Type moduleType) {
return getSupportedProfiles();
}
@Override
public Set<Type> getSupportedTypes() {
return Collections.unmodifiableSet(MODULE_TYPES);
}
@Override
public Set/*<String>*/ getSupportedJavaPlatformVersions() {
Set versions = new HashSet();
versions.add("1.7"); // NOI18N
versions.add("1.8"); // NOI18N
versions.add("1.8"); // NOI18N
versions.add("1.9"); // NOI18N
versions.add("11"); // NOI18N
if (this.properties.getServerVersion().compareToIgnoreUpdate(WildflyPluginUtils.EAP_7_0) >= 0) {
versions.add("17"); // NOI18N
}
return versions;
}
@Override
public JavaPlatform getJavaPlatform() {
return properties.getJavaPlatform();
}
@Override
public File[] getPlatformRoots() {
return new File[]{getServerHome(), getDomainHome()};
}
@Override
public File getServerHome() {
return properties.getRootDir();
}
@Override
public File getDomainHome() {
return properties.getServerDir();
}
@Override
public File getMiddlewareHome() {
return null;
}
private static class FF implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".jar") || new File(dir, name).isDirectory(); //NOI18N
}
}
@Override
public LibraryImplementation[] getLibraries() {
if (libraries == null) {
initLibraries();
}
return libraries.clone();
}
public void notifyLibrariesChanged() {
initLibraries();
firePropertyChange(PROP_LIBRARIES, null, libraries.clone());
}
@Override
public java.awt.Image getIcon() {
return null;
}
@Override
public String getDisplayName() {
return NbBundle.getMessage(WildflyJ2eePlatformFactory.class, "TITLE_JBOSS_FACTORY");
}
@Override
@Deprecated
public boolean isToolSupported(String toolName) {
if (J2eePlatform.TOOL_JSR109.equals(toolName)) {
if (containsJaxWsLibraries()) {
return true;
}
}
if (J2eePlatform.TOOL_WSIMPORT.equals(toolName)) {
if (containsJaxWsLibraries()) {
return true;
}
}
if (J2eePlatform.TOOL_WSGEN.equals(toolName)) {
if (containsJaxWsLibraries()) {
return true;
}
}
if ("JaxWs-in-j2ee14-supported".equals(toolName)) { //NOI18N
if (containsJaxWsLibraries()) {
return true;
}
}
if (!containsJaxWsLibraries()
&& (J2eePlatform.TOOL_WSCOMPILE.equals(toolName) || J2eePlatform.TOOL_APP_CLIENT_RUNTIME.equals(toolName))) {
return true;
}
if (HIBERNATE_JPA_PROVIDER.equals(toolName)
|| TOPLINK_JPA_PROVIDER.equals(toolName)
|| KODO_JPA_PROVIDER.equals(toolName)) {
return containsPersistenceProvider(toolName);
}
if ("jpaversionverification".equals(toolName)) { // NOI18N
return true;
}
if ("jpa1.0".equals(toolName)) { // NOI18N
return true;
}
if ("jpa2.0".equals(toolName)) { // NOI18N
return true;
}
if ("jpa2.1".equals(toolName)) { // NOI18N
return this.properties.isWildfly();
}
if ("jpa3.0".equals(toolName)) { // NOI18N
return this.properties.isWildfly();
}
if ("jpa3.1".equals(toolName)) { // NOI18N
return this.properties.isWildfly();
}
if ("hibernatePersistenceProviderIsDefault2.0".equals(toolName)) {
return true;
}
if ("defaultPersistenceProviderJavaEE5".equals(toolName)) {
return true;
}
return false;
}
String getDefaultJpaProvider() {
return HIBERNATE_JPA_PROVIDER;
}
private boolean containsJaxWsLibraries() {
File[] jaxWsAPILib = new File(properties.getModulePath("org/jboss/ws/api/main")).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith("jbossws-api") && name.endsWith("jar");
}
}); // NOI18N
if (jaxWsAPILib != null && jaxWsAPILib.length == 1 && jaxWsAPILib[0].exists()) {
return true;
}
jaxWsAPILib = new File(properties.getModulePath("javax/xml/ws/api/main")).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith("jboss-jaxws-api") && name.endsWith("jar");
}
}); // NOI18N
if (jaxWsAPILib != null && jaxWsAPILib.length == 1 && jaxWsAPILib[0].exists()) {
return true;
}
return false;
}
boolean containsPersistenceProvider(String providerName) {
return containsService(libraries, "javax.persistence.spi.PersistenceProvider", providerName);
}
private static boolean containsService(LibraryImplementation[] libraries, String serviceName, String serviceImplName) {
for (LibraryImplementation libImpl : libraries) {
if (containsService(libImpl, serviceName, serviceImplName)) { //NOI18N
return true;
}
}
return false;
}
private static boolean containsService(LibraryImplementation library, String serviceName, String serviceImplName) {
List roots = library.getContent(J2eeLibraryTypeProvider.VOLUME_TYPE_CLASSPATH);
for (Iterator it = roots.iterator(); it.hasNext();) {
URL rootUrl = (URL) it.next();
FileObject root = URLMapper.findFileObject(rootUrl);
if (root != null && "jar".equals(rootUrl.getProtocol())) { //NOI18N
FileObject archiveRoot = FileUtil.getArchiveRoot(FileUtil.getArchiveFile(root));
String serviceRelativePath = "META-INF/services/" + serviceName; //NOI18N
FileObject serviceFO = archiveRoot.getFileObject(serviceRelativePath);
if (serviceFO != null && containsService(serviceFO, serviceName, serviceImplName)) {
return true;
}
}
}
return false;
}
private static boolean containsService(FileObject serviceFO, String serviceName, String serviceImplName) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(serviceFO.getInputStream()));
try {
String line;
while ((line = br.readLine()) != null) {
int ci = line.indexOf('#');
if (ci >= 0) {
line = line.substring(0, ci);
}
if (line.trim().equals(serviceImplName)) {
return true;
}
}
} finally {
br.close();
}
} catch (Exception ex) {
Exceptions.attachLocalizedMessage(ex, serviceFO.toURL().toString());
Logger.getLogger("global").log(Level.INFO, null, ex);
}
return false;
}
@Override
public File[] getToolClasspathEntries(String toolName) {
if (J2eePlatform.TOOL_WSIMPORT.equals(toolName)) {
return getJaxWsLibraries();
}
if (J2eePlatform.TOOL_WSGEN.equals(toolName)) {
return getJaxWsLibraries();
}
if (J2eePlatform.TOOL_WSCOMPILE.equals(toolName)) {
File root = InstalledFileLocator.getDefault().locate("modules/ext/jaxrpc16", null, false); // NOI18N
return new File[]{
new File(root, "saaj-api.jar"), // NOI18N
new File(root, "saaj-impl.jar"), // NOI18N
new File(root, "jaxrpc-api.jar"), // NOI18N
new File(root, "jaxrpc-impl.jar"), // NOI18N
};
}
if (J2eePlatform.TOOL_APP_CLIENT_RUNTIME.equals(toolName)) {
return new File(properties.getRootDir(), "client").listFiles(new FF()); // NOI18N
}
return null;
}
private File[] getJaxWsLibraries() {
File root = new File(properties.getRootDir(), "client"); // NOI18N
File jaxWsAPILib = new File(root, "jboss-jaxws.jar"); // NOI18N
// JBoss without jbossws
if (jaxWsAPILib.exists()) {
return new File[]{
new File(root, "wstx.jar"), // NOI18N
new File(root, "jaxws-tools.jar"), // NOI18N
new File(root, "jboss-common-client.jar"), // NOI18N
new File(root, "jboss-logging-spi.jar"), // NOI18N
new File(root, "stax-api.jar"), // NOI18N
new File(root, "jbossws-client.jar"), // NOI18N
new File(root, "jboss-jaxws-ext.jar"), // NOI18N
new File(root, "jboss-jaxws.jar"), // NOI18N
new File(root, "jboss-saaj.jar") // NOI18N
};
}
jaxWsAPILib = new File(root, "jbossws-native-jaxws.jar"); // NOI18N
// JBoss+jbossws-native
if (jaxWsAPILib.exists()) {
return new File[]{
new File(root, "wstx.jar"), // NOI18N
new File(root, "jaxws-tools.jar"), // NOI18N
new File(root, "jboss-common-client.jar"), // NOI18N
new File(root, "jboss-logging-spi.jar"), // NOI18N
new File(root, "stax-api.jar"), // NOI18N
new File(root, "jbossws-native-client.jar"), // NOI18N
new File(root, "jbossws-native-jaxws-ext.jar"), // NOI18N
new File(root, "jbossws-native-jaxws.jar"), // NOI18N
new File(root, "jbossws-native-saaj.jar") // NOI18N
};
}
jaxWsAPILib = new File(root, "jaxws-api.jar"); // NOI18N
// JBoss+jbossws-metro
if (jaxWsAPILib.exists()) {
return new File[]{
new File(root, "wstx.jar"), // NOI18N
new File(root, "jaxws-tools.jar"), // NOI18N
new File(root, "jboss-common-client.jar"), // NOI18N
new File(root, "jboss-logging-spi.jar"), // NOI18N
new File(root, "stax-api.jar"), // NOI18N
new File(root, "jbossws-metro-client.jar"), // NOI18N
new File(root, "saaj-api.jar") // NOI18N
};
}
return null;
}
@Override
@Deprecated
public String getToolProperty(String toolName, String propertyName) {
if (J2eePlatform.TOOL_APP_CLIENT_RUNTIME.equals(toolName)) {
if (J2eePlatform.TOOL_PROP_MAIN_CLASS.equals(propertyName)) {
return ""; // NOI18N
}
if (J2eePlatform.TOOL_PROP_MAIN_CLASS_ARGS.equals(propertyName)) {
return ""; // NOI18N
}
if ("j2ee.clientName".equals(propertyName)) { // NOI18N
return "${jar.name}"; // NOI18N
}
if (J2eePlatform.TOOL_PROP_JVM_OPTS.equals(propertyName)) {
return " -Djava.naming.factory.url.pkgs=org.jboss.ejb.client.naming"; // NOI18N
}
}
return null;
}
// private helper methods -------------------------------------------------
private void initLibraries() {
// create library
LibraryImplementation lib = new J2eeLibraryTypeProvider().createLibrary();
lib.setName(NbBundle.getMessage(WildflyJ2eePlatformFactory.class, "TITLE_JBOSS_LIBRARY"));
lib.setContent(J2eeLibraryTypeProvider.VOLUME_TYPE_CLASSPATH, properties.getClasses());
lib.setContent(J2eeLibraryTypeProvider.VOLUME_TYPE_JAVADOC, properties.getJavadocs());
lib.setContent(J2eeLibraryTypeProvider.VOLUME_TYPE_SRC, properties.getSources());
libraries = new LibraryImplementation[]{lib};
}
@Override
public Lookup getLookup() {
WSStack<JaxWs> wsStack = WSStackFactory.createWSStack(JaxWs.class,
new JBossJaxWsStack(properties.getRootDir()), WSStack.Source.SERVER);
Lookup baseLookup = Lookups.fixed(properties.getRootDir(),
wsStack, new JpaSupportImpl(this), new JaxRsStackSupportImpl(this));
return LookupProviderSupport.createCompositeLookup(baseLookup,
"J2EE/DeploymentPlugins/Wildlfy/Lookup"); //NOI18N
}
private class JaxRsStackSupportImpl implements JaxRsStackSupportImplementation {
private static final String JAX_RS_APPLICATION_CLASS = "javax.ws.rs.core.Application"; //NOI18N
private J2eePlatformImplImpl j2eePlatform;
JaxRsStackSupportImpl(J2eePlatformImplImpl j2eePlatform) {
this.j2eePlatform = j2eePlatform;
}
@Override
public boolean addJsr311Api(Project project) {
return isBundled(JAX_RS_APPLICATION_CLASS);
}
@Override
public boolean extendsJerseyProjectClasspath(Project project) {
return isBundled(JAX_RS_APPLICATION_CLASS);
}
@Override
public void removeJaxRsLibraries(Project project) {
}
@Override
public void configureCustomJersey(Project project) {
}
@Override
public boolean isBundled(String classFqn) {
j2eePlatform.getLibraries();
for (LibraryImplementation lib : j2eePlatform.getLibraries()) {
List<URL> urls = lib.getContent(J2eeLibraryTypeProvider.VOLUME_TYPE_CLASSPATH);
for (URL url : urls) {
FileObject root = URLMapper.findFileObject(url);
if (FileUtil.isArchiveFile(root)) {
root = FileUtil.getArchiveRoot(root);
}
String path = classFqn.replace('.', '/') + ".class"; //NOI18N
if (root.getFileObject(path) != null) {
return true;
}
}
}
return false;
}
}
}
}