blob: 8f19e0aaeb3ad8e8c54ef23d665363a0799f77af [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.glassfish.javaee;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.netbeans.modules.glassfish.tooling.data.GlassFishLibrary;
import org.netbeans.modules.glassfish.tooling.data.GlassFishServer;
import org.netbeans.modules.glassfish.tooling.server.config.ConfigBuilder;
import org.netbeans.modules.glassfish.tooling.server.config.ConfigBuilderProvider;
import org.netbeans.api.project.libraries.Library;
import org.netbeans.api.project.libraries.LibraryManager;
import static org.netbeans.modules.glassfish.javaee.ide.Hk2PluginProperties.fileToUrl;
import org.netbeans.modules.j2ee.deployment.common.api.J2eeLibraryTypeProvider;
import org.netbeans.spi.project.libraries.LibraryImplementation;
import org.openide.ErrorManager;
import org.openide.filesystems.FileUtil;
import org.openide.modules.InstalledFileLocator;
/**
* GlassFish bundled libraries provider.
* <p/>
* Builds <code>Library</code> instance containing Jersey library from GlassFish
* modules. Actually only GlassFish v3 and v4 are supported.
* <p/>
* @author Tomas Kraus, Peter Benedikovic
*/
public class Hk2LibraryProvider /*implements JaxRsStackSupportImplementation*/ {
////////////////////////////////////////////////////////////////////////////
// Class attributes //
////////////////////////////////////////////////////////////////////////////
/** Library provider type. */
private static final String PROVIDER_TYPE = "j2se";
/** Java EE library name suffix to be added after server instance name.
* Java EE library name must be unique so combination of instance name
* and some common suffix is used. */
private static final String JAVAEE_NAME_SUFFIX = " Java EE";
/** Java EE library name suffix to be added after server instance name.
* Jersey library name must be unique so combination of instance name
* and some common suffix is used. */
private static final String JERSEY_NAME_SUFFIX = " Jersey";
/** JAX-RS library name suffix to be added after server instance name.
* JAX-RS library name must be unique so combination of instance name
* and some common suffix is used. */
private static final String JAXRS_NAME_SUFFIX = " JAX-RS";
/** Java EE library name pattern to search for it in
* <code>GlassFishLibrary</code> list. */
private Pattern JAVAEE_PATTERN = Pattern.compile("[jJ]ava {0,1}[eE]{2}");
/** Jersey library name pattern to search for it in
* <code>GlassFishLibrary</code> list. */
private Pattern JERSEY_PATTERN = Pattern.compile("[jJ]ersey.*");
/** JAX-RS library name pattern to search for it in
* <code>GlassFishLibrary</code> list. */
private Pattern JAXRS_PATTERN
= Pattern.compile("[jJ][aA][xX][ -]{0,1}[rR][sS]");
/** Code base for file locator. */
static final String JAVAEE_DOC_CODE_BASE
= "org.netbeans.modules.j2ee.platform";
/** Internal {@see GlassFishServer} to {@see Hk2LibraryProvider}
* mapping. */
private static final Map <GlassFishServer, Hk2LibraryProvider> providers
= new HashMap<>();
////////////////////////////////////////////////////////////////////////////
// Static methods //
////////////////////////////////////////////////////////////////////////////
/**
* Returns {@see Hk2LibraryProvider} class instance for specific server
* instance.
* <p/>
* Provider instances for individual {@see GlassFishServer} instances
* are shared.
* <p/>
* @param server {@see GlassFishServer} instance for which provider
* is returned.
* @return {@see Hk2LibraryProvider} class instance for given server
* instance.
*/
public static Hk2LibraryProvider getProvider(GlassFishServer server) {
Hk2LibraryProvider provider;
synchronized(providers) {
if ((provider = providers.get(server)) == null)
providers.put(
server, provider = new Hk2LibraryProvider(server));
}
return provider;
}
////////////////////////////////////////////////////////////////////////////
// Instance attributes //
////////////////////////////////////////////////////////////////////////////
/** Library builder associated with current platform.
* This attribute should be accessed only using {@see #getBuilder()} even
* internally. */
private volatile ConfigBuilder builder;
/** GlassFish server home directory. */
private final String serverHome;
/** GlassFish server name. */
private final String serverName;
/** GlassFish server instance. */
private final GlassFishServer server;
/** Java EE library name associated with current GlassFish server context.
* This is lazy initialized internal cache. Do not access this attribute
* outside {@see #getJavaEEName()} method! */
private volatile String javaEEName = null;
/** Jersey library name associated with current GlassFish server context.
* This is lazy initialized internal cache. Do not access this attribute
* outside {@see #getJerseyName()} method! */
private volatile String jerseyName = null;
/** Jersey JAX-RS name associated with current GlassFish server context.
* This is lazy initialized internal cache. Do not access this attribute
* outside {@see #getJaxRsName()} method! */
private volatile String jaxRsName = null;
////////////////////////////////////////////////////////////////////////////
// Constructors //
////////////////////////////////////////////////////////////////////////////
/**
* Creates an instance of Jersey library provider.
* <p/>
* @param server GlassFish server entity.
*/
private Hk2LibraryProvider(GlassFishServer server) {
if (server == null) {
throw new IllegalArgumentException(
"GlassFish server entity shall not be null.");
}
serverHome = server.getServerHome();
serverName = server.getName();
this.server = server;
}
////////////////////////////////////////////////////////////////////////////
// Methods //
////////////////////////////////////////////////////////////////////////////
/**
* Get Java EE library name for this server context.
* <p/>
* This library name shall be registered in default {@see LibraryManager}
* and is unique for Jersey modules of given GlassFish server instance.
* Library name is cached after first usage.
* <p/>
* @return Java EE library name for this server context.
*/
public String getJavaEEName() {
if (javaEEName != null) {
return javaEEName;
}
synchronized (this) {
StringBuilder sb = new StringBuilder(
serverName.length() + JAVAEE_NAME_SUFFIX.length());
sb.append(serverName);
sb.append(JAVAEE_NAME_SUFFIX);
javaEEName = sb.toString();
}
return javaEEName;
}
/**
* Get Jersey library name for this server context.
* <p/>
* This library name shall be registered in default {@see LibraryManager}
* and is unique for Jersey modules of given GlassFish server instance.
* Library name is cached after first usage.
* <p/>
* @return Jersey library name for this server context.
*/
public String getJerseyName() {
if (jerseyName != null) {
return jerseyName;
}
synchronized (this) {
StringBuilder sb = new StringBuilder(
serverName.length() + JERSEY_NAME_SUFFIX.length());
sb.append(serverName);
sb.append(JERSEY_NAME_SUFFIX);
jerseyName = sb.toString();
}
return jerseyName;
}
/**
* Get JAX-RS library name for this server context.
* <p/>
* This library name shall be registered in default {@see LibraryManager}
* and is unique for Jersey modules of given GlassFish server instance.
* Library name is cached after first usage.
* <p/>
* @return JAX-RS library name for this server context.
*/
public String getJaxRsName() {
if (jaxRsName != null) {
return jaxRsName;
}
synchronized (this) {
StringBuilder sb = new StringBuilder(
serverName.length() + JAXRS_NAME_SUFFIX.length());
sb.append(serverName);
sb.append(JAXRS_NAME_SUFFIX);
jaxRsName = sb.toString();
}
return jaxRsName;
}
/**
* Return Jersey libraries available in GlassFish.
* <p/>
* @return Jersey libraries available in GlassFish.
*/
public Library getJerseyLibrary() {
return getLibrary(JERSEY_PATTERN, getJerseyName());
}
/**
* Set {@see LibraryImplementation} content for Jersey libraries
* available in GlassFish.
* <p/>
* @param lib Target {@see LibraryImplementation}.
* @param libraryName Library name in returned Library instance.
*/
public void setJerseyImplementation(
LibraryImplementation lib, String libraryName) {
setLibraryImplementationContent(lib, JERSEY_PATTERN, libraryName);
}
/**
* Get {@see List} of class path {@see URL}s for Jersey libraries.
* <p/>
* @return {@see List} of class path {@see URL}s for Jersey libraries.
*/
public List<URL> getJerseyClassPathURLs() {
return getLibraryClassPathURLs(JERSEY_PATTERN);
}
/**
* Return JAX-RS libraries available in GlassFish.
* <p/>
* @return JAX-RS libraries available in GlassFish.
*/
public Library getJaxRsLibrary() {
return getLibrary(JAXRS_PATTERN, getJaxRsName());
}
/**
* Set {@see LibraryImplementation} content for JAX-RS libraries
* available in GlassFish.
* <p/>
* @param lib Target {@see LibraryImplementation}.
* @param libraryName Library name in returned Library instance.
*/
public void setJaxRsLibraryImplementation(
LibraryImplementation lib, String libraryName) {
setLibraryImplementationContent(lib, JAXRS_PATTERN, libraryName);
}
/**
* Get {@see List} of class path {@see URL}s for JAX-RS libraries.
* <p/>
* @return {@see List} of class path {@see URL}s for JAX-RS libraries.
*/
public List<URL> getJaxRsClassPathURLs() {
return getLibraryClassPathURLs(JAXRS_PATTERN);
}
/**
* Return Java EE libraries available in GlassFish.
* <p/>
* @return Java EE libraries available in GlassFish\.
*/
public Library getJavaEELibrary() {
return getLibrary(JAVAEE_PATTERN, getJavaEEName());
}
/**
* Set {@see LibraryImplementation} content for Java EE libraries
* available in GlassFish.
* <p/>
* @param lib Target {@see LibraryImplementation}.
* @param libraryName Library name in returned Library instance.
*/
public void setJavaEELibraryImplementation(
LibraryImplementation lib, String libraryName) {
setLibraryImplementationContent(lib, JAVAEE_PATTERN, libraryName);
}
/**
* Get {@see List} of class path {@see URL}s for Java EE libraries.
* <p/>
* @return {@see List} of class path {@see URL}s for Java EE libraries.
*/
public List<URL> getJavaEEClassPathURLs() {
return getLibraryClassPathURLs(JAVAEE_PATTERN);
}
/**
* Return libraries available in GlassFish.
* <p/>
* @param namePattern Library name pattern to search for it in
* <code>GlassFishLibrary</code> list.
* @param libraryName Library name in returned Library instance.
* @return Requested GlassFish library.
*/
private Library getLibrary(Pattern namePattern, String libraryName) {
Library lib = LibraryManager.getDefault().getLibrary(libraryName);
if (lib != null) {
return lib;
}
ConfigBuilder cb = ConfigBuilderProvider.getBuilder(server);
List<GlassFishLibrary> gfLibs = cb.getLibraries(server.getVersion());
for (GlassFishLibrary gfLib : gfLibs) {
if (namePattern.matcher(gfLib.getLibraryID()).matches()) {
Map<String,List<URL>> contents
= new HashMap<String, List<URL>>(1);
Map<String, String> properties = new HashMap<String, String>(2);
contents.put("classpath", translateArchiveUrls(gfLib.getClasspath()));
contents.put("javadoc", translateArchiveUrls(gfLib.getJavadocs()));
properties.put("maven-dependencies", gfLib.getMavenDeps());
properties.put("maven-repositories", "default");
try {
return LibraryManager.getDefault().createLibrary(
PROVIDER_TYPE,
libraryName,
null,
null,
contents,
properties);
} catch (IOException ioe) {
Logger.getLogger("glassfish-javaee").log(Level.WARNING,
"Could not create Jersey library for "
+ serverName + ": ", ioe);
}
}
}
return null;
}
/**
* Set {@see LibraryImplementation} content for given library name.
* <p/>
* @param lib Target {@see LibraryImplementation}.
* @param namePattern Library name pattern to search for it in
* <code>GlassFishLibrary</code> list.
* @param libraryName Library name in returned Library instance.
*/
private void setLibraryImplementationContent(LibraryImplementation lib,
Pattern namePattern, String libraryName) {
ConfigBuilder cb = ConfigBuilderProvider.getBuilder(server);
List<GlassFishLibrary> gfLibs = cb.getLibraries(server.getVersion());
for (GlassFishLibrary gfLib : gfLibs) {
if (namePattern.matcher(gfLib.getLibraryID()).matches()) {
List<String> javadocLookups = gfLib.getJavadocLookups();
lib.setName(libraryName);
// Build class path
List<URL> cp = new ArrayList<URL>();
for (URL url : gfLib.getClasspath()) {
if (FileUtil.isArchiveFile(url)) {
cp.add(FileUtil.getArchiveRoot(url));
} else {
cp.add(url);
}
}
// Build java docs
List<URL> javadoc = new ArrayList<URL>();
if (javadocLookups != null) {
for (String lookup : javadocLookups) {
try {
File j2eeDoc = InstalledFileLocator
.getDefault().locate(lookup,
JAVAEE_DOC_CODE_BASE, false);
if (j2eeDoc != null) {
javadoc.add(fileToUrl(j2eeDoc));
}
} catch (MalformedURLException e) {
ErrorManager.getDefault()
.notify(ErrorManager.INFORMATIONAL, e);
}
}
}
lib.setContent(J2eeLibraryTypeProvider.VOLUME_TYPE_CLASSPATH,
cp);
lib.setContent(J2eeLibraryTypeProvider.VOLUME_TYPE_JAVADOC,
javadoc);
}
}
}
/**
* Get list of class path {@see URL}s for given library name.
* <p/>
* @param namePattern Library name pattern to search for it in
* <code>GlassFishLibrary</code> list.
* @param libraryName Library name in returned Library instance.
*/
private List<URL> getLibraryClassPathURLs(Pattern namePattern) {
ConfigBuilder cb = ConfigBuilderProvider.getBuilder(server);
List<GlassFishLibrary> gfLibs = cb.getLibraries(server.getVersion());
for (GlassFishLibrary gfLib : gfLibs) {
if (namePattern.matcher(gfLib.getLibraryID()).matches()) {
return gfLib.getClasspath();
}
}
return Collections.<URL>emptyList();
}
private List<URL> translateArchiveUrls(List<URL> urls) {
List<URL> result = new ArrayList<>(urls.size());
for (URL u : urls) {
if (FileUtil.isArchiveFile(u)) {
result.add(FileUtil.getArchiveRoot(u));
} else {
result.add(u);
}
}
return result;
}
}