blob: 3a17762b28e7313c21e7418c70b4a4c0df9f3bfa [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.spi;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.server.ServerInstance;
import org.netbeans.modules.glassfish.common.GlassfishInstanceProvider;
import org.netbeans.modules.glassfish.common.ServerDetails;
import org.netbeans.modules.glassfish.common.wizards.GlassfishWizardProvider;
import org.netbeans.spi.server.ServerInstanceProvider;
import org.openide.WizardDescriptor;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Lookup;
/**
* General helper methods for accessing GlassFish server objects.
*
* @author Peter Williams
* @author Ludovic Champenois
*/
public final class ServerUtilities {
public static final int ACTION_TIMEOUT = 15000;
public static final TimeUnit ACTION_TIMEOUT_UNIT = TimeUnit.MILLISECONDS;
public static final String GFV3_MODULES_DIR_NAME = "modules"; // NOI18N
public static final String GFV3_LIB_DIR_NAME = "lib"; // NOI18N
public static final String GFV3_VERSION_MATCHER = "(?:-[0-9bSNAPHOT]+(?:\\.[0-9]+(?:_[0-9]+|)|).*|).jar"; // NOI18N
public static final String GFV3_JAR_MATCHER = "glassfish" + GFV3_VERSION_MATCHER; // NOI18N
public static final String PROP_FIRST_RUN = "first_run";
private GlassfishInstanceProvider gip;
private GlassfishWizardProvider gwp;
private ServerUtilities(GlassfishInstanceProvider gip, GlassfishWizardProvider gwp) {
assert null != gip;
this.gip = gip;
this.gwp = gwp;
}
// public static ServerUtilities getPreludeUtilities() {
// GlassfishInstanceProvider gip = GlassfishInstanceProvider.getPrelude();
// return null == gip ? null : new ServerUtilities(gip,null);
// }
public static ServerUtilities getEe6Utilities() {
GlassfishInstanceProvider gip = GlassfishInstanceProvider.getProvider();
return null == gip ? null : new ServerUtilities(gip,
GlassfishWizardProvider.createEe6());
}
public static ServerUtilities getEe7Utilities() {
GlassfishInstanceProvider gip = GlassfishInstanceProvider.getProvider();
return null == gip ? null : new ServerUtilities(gip,
GlassfishWizardProvider.createEe7());
}
public static ServerUtilities getEe8Utilities() {
GlassfishInstanceProvider gip = GlassfishInstanceProvider.getProvider();
return null == gip ? null : new ServerUtilities(gip,
GlassfishWizardProvider.createEe8());
}
public static ServerUtilities getJakartaEe8Utilities() {
GlassfishInstanceProvider gip = GlassfishInstanceProvider.getProvider();
return null == gip ? null : new ServerUtilities(gip,
GlassfishWizardProvider.createJakartaEe8());
}
public static ServerUtilities getJakartaEe9Utilities() {
GlassfishInstanceProvider gip = GlassfishInstanceProvider.getProvider();
return null == gip ? null : new ServerUtilities(gip,
GlassfishWizardProvider.createJakartaEe9());
}
public static ServerUtilities getJakartaEe91Utilities() {
GlassfishInstanceProvider gip = GlassfishInstanceProvider.getProvider();
return null == gip ? null : new ServerUtilities(gip,
GlassfishWizardProvider.createJakartaEe91());
}
public static ServerUtilities getJakartaEe10Utilities() {
GlassfishInstanceProvider gip = GlassfishInstanceProvider.getProvider();
return null == gip ? null : new ServerUtilities(gip,
GlassfishWizardProvider.createJakartaEe10());
}
// public static ServerUtilities getEe6WCUtilities() {
// GlassfishInstanceProvider gip = GlassfishInstanceProvider.getProvider();
// return null == gip ? null : new ServerUtilities(gip,
// GlassfishWizardProvider.createEe6WC());
// }
/**
* Returns the ServerInstance object for the server with the specified URI.
*
* @param uri uri identifying the server instance.
*
* @return ServerInstance object for this server instance.
*/
public ServerInstance getServerInstance(String uri) {
ServerInstance retVal = gip.getInstance(uri);
return retVal;
}
/**
* Creates an iterator for a wizard to instantiate server objects.
* <p/>
* @return Server wizard iterator initialized with supported GlassFish
* server versions.
*/
public static WizardDescriptor.InstantiatingIterator
getInstantiatingIterator() {
return ServerDetails.getInstantiatingIterator();
}
/**
* Returns true if this server is registered or is in the process of being
* registered.
*
* @param uri uri identifying the server instance.
*
* @return True if this server is or is being registered, false otherwise.
*/
public boolean isRegisteredUri(String uri) {
return gip.getInstance(uri) != null ||
GlassfishInstanceProvider.activeRegistrationSet.contains(uri);
}
/**
* Returns the lookup object for a server instance when the caller only has
* the public handle available via common server API.
*
* @param ServerInstance object for this server instance.
*
* @return Lookup object maintained by backing instance implementation
*/
public Lookup getLookupFor(ServerInstance instance) {
return gip.getLookupFor(instance);
}
/**
* Returns the facade implementation for the specified server, if that server
* supports the facade class passed in.
*
* @param uri uri identifying the server instance.
* @param serverFacadeClass class definition of the server facade we're
* looking for.
*
* @return facade implementation for specified server or null if either the
* server does not exist or the server does not implement this facade.
*/
public <T> T getInstanceByCapability(String uri, Class <T> serverFacadeClass) {
return gip.getInstanceByCapability(uri, serverFacadeClass);
}
/**
* Returns a list of the server instances that support the facade class
* specified (e.g. all servers that support <code>RubyInstance</code>).
*
* @param serverFacadeClass class definition of the server facade we're
* looking for.
*
* @return list of servers that support the interface specified or an empty
* list if no servers support that interface.
*/
public<T> List<T> getInstancesByCapability(Class<T> serverFacadeClass) {
return gip.getInstancesByCapability(serverFacadeClass);
}
/**
* Returns the ServerInstanceImplementation instance for the server with the
* specified URI. Use when you need to avoid calling through the ServerInstance
* facade wrapper. Otherwise, you should call <code>getServerInstance()</code> instead.
*
* @param uri uri identifying the server instance.
*
* @return ServerInstanceImplementation object for this server instance.
*/
// public static ServerInstanceImplementation getInternalServerInstance(String uri) {
// return GlassfishInstanceProvider.getDefault().getInternalInstance(uri);
// }
/**
* Returns the ServerInstanceProvider for this server plugin so we don't
* have to look it up via common server SPI.
*
* @return the GlassFish V3 impl for ServerInstanceProvider.
*/
public ServerInstanceProvider getServerProvider() {
return gip;
}
/**
* Returns the fqn jar name with the correct version
*
* @return the File with full path of the jar or null
*/
public static File getJarName(String glassfishInstallRoot, String jarNamePattern) {
return getJarName(glassfishInstallRoot, jarNamePattern, GFV3_MODULES_DIR_NAME);
}
public static File getJarName(String glassfishInstallRoot, String jarNamePattern, String subdirectoryName) {
File searchDirectory = new File(glassfishInstallRoot + File.separatorChar + subdirectoryName);
return Utils.getFileFromPattern(jarNamePattern, searchDirectory);
}
/**
* Returns the fqn jar name with the correct version
*
* @return the File with full path of the jar or null
*/
public static File getWsJarName(String glassfishInstallRoot, String jarNamePattern) {
File modulesDir = new File(glassfishInstallRoot + File.separatorChar + GFV3_MODULES_DIR_NAME);
File retVal = Utils.getFileFromPattern(jarNamePattern, modulesDir);
if (null == retVal) {
retVal = Utils.getFileFromPattern(jarNamePattern,
new File(modulesDir,"endorsed"));
}
return retVal;
}
/**
* Get the url for a file, including proper protocol for archive files (jars).
*
* @param file File to create URL from.
*
* @return url URL for file with proper protocol specifier.
*
* @throws java.net.MalformedURLException
*/
public static URL fileToUrl(File file) throws MalformedURLException {
URL url = file.toURI().toURL();
if (FileUtil.isArchiveFile(url)) {
url = FileUtil.getArchiveRoot(url);
}
return url;
}
/**
* Surround the submitted string with quotes if it contains any embedded
* whitespace characters.
*
* Implementation note: Do not trim the submitted string. Assume all
* whitespace character are part of a file name or path that requires
* quotes.
*
* !PW FIXME handles only spaces right now. Should handle all whitespace.
* !PW FIMME 4NT completion on Windows quotes paths if a folder has a comma
* in the name. Might need that too, though I haven't proved it yet. *
* @param path
* @return
*/
public static final String quote(String path) {
return path.indexOf(' ') == -1 ? path : "\"" + path + "\"";
}
/**
* Determine if the named directory is a TP2 install.
*
* @param gfRoot the name of the directory to check against.
* @return true if the directory appears to be the root of a TP2 installation.
*/
public static boolean isTP2(String gfRoot) {
return ServerUtilities.getJarName(gfRoot, ServerUtilities.GFV3_JAR_MATCHER).getName().indexOf("-tp-2-") > -1; // NOI18N
}
/**
* create a list of jars that appear to be Java EE api jars that live in the
* modules directory.
*
* @param jarList the list "so far"
* @param parent the directory to look into. Should not be null.
* @param depth depth of the server
* @param escape pass true if backslashes in jar names should be escaped
* @return the complete list of jars that match the selection criteria
*/
public static List<String> filterByManifest(List<String> jarList, FileObject parent, int depth, boolean escape) {
// be kind to clients that pass in null
if(null != parent) {
int parentLength = parent.getPath().length();
/* modules/web/jsf-impl.jar was not seen (or added with wrong relative name).
* need to calculate size relative to the modules/ dir and not the subdirs
* notice: this works only for depth=0 or 1
* not need to make it work deeper anyway
* with this test, we now also return "web/jsf-impl.jar" which is correct
*/
if (depth==1){
parentLength = parent.getParent().getPath().length();
}
for(FileObject candidate: parent.getChildren()) {
if(candidate.isFolder()) {
if(depth < 1) {
filterByManifest(jarList, candidate, depth+1, escape);
}
continue;
} else if(!candidate.getNameExt().endsWith(".jar")) {
continue;
}
try (JarFile jarFile = new JarFile(FileUtil.toFile(candidate), false)) {
Manifest manifest = jarFile.getManifest();
if(manifest != null) {
Attributes attrs = manifest.getMainAttributes();
if(attrs != null) {
String bundleName = attrs.getValue("Bundle-SymbolicName");
//String bundleName = attrs.getValue("Extension-Name");
if(bundleName != null && bundleName.contains("javax")) {
String val = candidate.getPath().substring(parentLength);
if(escape) {
val = val.replace("\\", "\\\\");
}
jarList.add(val);
}
}
}
} catch (IOException ex) {
Logger.getLogger(ServerUtilities.class.getName()).log(Level.INFO,
candidate.getPath(), ex);
}
}
} else {
Logger.getLogger(ServerUtilities.class.getName()).log(Level.FINER,
"Null FileObject passed in as the parent parameter. Returning the original list");
}
return jarList;
}
}