/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2008-2013 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.glassfish.javaee.core.deployment; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.inject.Inject; import com.sun.enterprise.config.serverbeans.Application; import com.sun.enterprise.config.serverbeans.Applications; import com.sun.enterprise.config.serverbeans.Module; import com.sun.enterprise.deployment.BundleDescriptor; import com.sun.enterprise.deployment.EjbBundleDescriptor; import com.sun.enterprise.deployment.EjbDescriptor; import com.sun.enterprise.deployment.WebBundleDescriptor; import com.sun.enterprise.deployment.WebComponentDescriptor; import com.sun.enterprise.deployment.util.DOLUtils; import com.sun.enterprise.util.LocalStringManagerImpl; import org.glassfish.api.ActionReport; import org.glassfish.api.I18n; import org.glassfish.api.Param; import org.glassfish.api.admin.AdminCommand; import org.glassfish.api.admin.AdminCommandContext; import org.glassfish.api.admin.CommandLock; import org.glassfish.api.admin.CommandRunner; import org.glassfish.api.admin.ExecuteOn; import org.glassfish.api.admin.ParameterMap; import org.glassfish.api.admin.RestEndpoint; import org.glassfish.api.admin.RestEndpoints; import org.glassfish.api.admin.RestParam; import org.glassfish.api.admin.RuntimeType; import org.glassfish.deployment.common.ModuleDescriptor; import org.glassfish.deployment.versioning.VersioningSyntaxException; import org.glassfish.deployment.versioning.VersioningUtils; import org.glassfish.internal.data.ApplicationInfo; import org.glassfish.internal.data.ApplicationRegistry; import org.glassfish.internal.deployment.Deployment; import org.jvnet.hk2.annotations.Service; import org.glassfish.hk2.api.PerLookup; /** * list-sub-components command */ @Service(name="list-sub-components") @I18n("list.sub.components") @PerLookup @CommandLock(CommandLock.LockType.NONE) @ExecuteOn(value={RuntimeType.DAS}) @RestEndpoints({ @RestEndpoint(configBean=Application.class, opType=RestEndpoint.OpType.GET, path="list-sub-components", description="List subcomponents", params={ @RestParam(name="modulename", value="$parent") }) }) public class ListSubComponentsCommand implements AdminCommand { @Param(primary=true) private String modulename = null; @Param(optional=true) private String appname = null; @Param(optional=true) private String type = null; @Inject public ApplicationRegistry appRegistry; @Param(optional=true, defaultValue="false") private Boolean resources = false; @Param(optional=true, defaultValue="false", shortName="t") public Boolean terse = false; @Inject public Deployment deployment; @Inject public Applications applications; @Inject private CommandRunner commandRunner; final private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(ListSubComponentsCommand.class); public void execute(AdminCommandContext context) { final ActionReport report = context.getActionReport(); ActionReport.MessagePart part = report.getTopMessagePart(); String applicationName = modulename; if (appname != null) { applicationName = appname; } try { VersioningUtils.checkIdentifier(applicationName); } catch (VersioningSyntaxException ex) { report.setMessage(ex.getLocalizedMessage()); report.setActionExitCode(ActionReport.ExitCode.FAILURE); return; } if (!deployment.isRegistered(applicationName)) { report.setMessage(localStrings.getLocalString("application.notreg","Application {0} not registered", applicationName)); report.setActionExitCode(ActionReport.ExitCode.FAILURE); return; } Application application = applications.getApplication(applicationName); if (application.isLifecycleModule()) { if (!terse) { part.setMessage(localStrings.getLocalString("listsubcomponents.no.elements.to.list", "Nothing to List.")); } return; } ApplicationInfo appInfo = appRegistry.get(applicationName); if (appInfo == null) { report.setMessage(localStrings.getLocalString("application.not.enabled","Application {0} is not in an enabled state", applicationName)); return; } com.sun.enterprise.deployment.Application app = appInfo.getMetaData(com.sun.enterprise.deployment.Application.class); if (app == null) { if (!terse) { part.setMessage(localStrings.getLocalString("listsubcomponents.no.elements.to.list", "Nothing to List.")); } return; } Map<String, String> subComponents ; Map<String, String> subComponentsMap = new HashMap<String, String>(); if (appname == null) { subComponents = getAppLevelComponents(app, type, subComponentsMap); } else { // strip the version suffix (delimited by colon), if present int versionSuffix = modulename.indexOf(':'); String versionLessModuleName = versionSuffix > 0 ? modulename.substring(0, versionSuffix) : modulename; BundleDescriptor bundleDesc = app.getModuleByUri(versionLessModuleName); if (bundleDesc == null) { report.setMessage(localStrings.getLocalString("listsubcomponents.invalidmodulename", "Invalid module name", appname, modulename)); report.setActionExitCode(ActionReport.ExitCode.FAILURE); return; } subComponents = getModuleLevelComponents( bundleDesc, type, subComponentsMap); } // the type param can only have values "ejbs" and "servlets" if (type != null) { if (!type.equals("servlets") && !type.equals("ejbs")) { report.setMessage(localStrings.getLocalString("listsubcomponents.invalidtype", "The type option has invalid value {0}. It should have a value of servlets or ejbs.", type)); report.setActionExitCode(ActionReport.ExitCode.FAILURE); return; } } List<String> subModuleInfos = new ArrayList<String>(); if (!app.isVirtual()) { subModuleInfos = getSubModulesForEar(app, type); } int[] longestValue = new int[2]; for (Map.Entry<String, String> entry : subComponents.entrySet()) { String key = entry.getKey(); if (key.length() > longestValue[0]) { longestValue[0] = key.length(); } String value = entry.getValue(); if (value.length() > longestValue[1]) { longestValue[1] = value.length(); } } StringBuilder formattedLineBuf = new StringBuilder(); for (int j = 0; j < 2; j++) { longestValue[j] += 2; formattedLineBuf.append("%-") .append(longestValue[j]) .append("s"); } String formattedLine = formattedLineBuf.toString(); if (!terse && subComponents.isEmpty()) { part.setMessage(localStrings.getLocalString("listsubcomponents.no.elements.to.list", "Nothing to List.")); } int i=0; for (String key : subComponents.keySet()) { ActionReport.MessagePart childPart = part.addChild(); childPart.setMessage( String.format(formattedLine, new Object[]{key, subComponents.get(key)} )); if (appname == null && !app.isVirtual()) { // we use the property mechanism to provide // support for JSR88 client if (subModuleInfos.get(i) != null) { childPart.addProperty("moduleInfo", subModuleInfos.get(i)); } } if (resources) { Module module = application.getModule(key); if (module != null) { ActionReport subReport = report.addSubActionsReport(); CommandRunner.CommandInvocation inv = commandRunner.getCommandInvocation("_list-resources", subReport, context.getSubject()); final ParameterMap parameters = new ParameterMap(); parameters.add("appname", application.getName()); parameters.add("modulename", module.getName()); inv.parameters(parameters).execute(); ActionReport.MessagePart subPart = subReport.getTopMessagePart(); for (ActionReport.MessagePart cp : subPart.getChildren()) { ActionReport.MessagePart resourcesChildPart = childPart.addChild(); resourcesChildPart.setMessage(" " + cp.getMessage()); } } } i++; } // add the properties for GUI to display Set<String> keys = subComponentsMap.keySet(); for (String key : keys) { part.addProperty(key, subComponentsMap.get(key)); } // now this is the normal output for the list-sub-components command report.setActionExitCode(ActionReport.ExitCode.SUCCESS); } // list sub components for ear private List<String> getSubModulesForEar(com.sun.enterprise.deployment.Application application, String type) { List<String> moduleInfoList = new ArrayList<String>(); Collection<ModuleDescriptor<BundleDescriptor>> modules = getSubModuleListForEar(application, type); for (ModuleDescriptor moduleDesc : modules) { String moduleInfo = moduleDesc.getArchiveUri() + ":" + moduleDesc.getModuleType(); if (moduleDesc.getModuleType().equals(DOLUtils.warType())) { moduleInfo = moduleInfo + ":" + moduleDesc.getContextRoot(); } moduleInfoList.add(moduleInfo); } return moduleInfoList; } private Map<String, String> getAppLevelComponents(com.sun.enterprise.deployment.Application application, String type, Map<String, String> subComponentsMap) { Map<String, String> subComponentList = new LinkedHashMap<String, String>(); if (application.isVirtual()) { // for standalone module, get servlets or ejbs BundleDescriptor bundleDescriptor = application.getStandaloneBundleDescriptor(); subComponentList = getModuleLevelComponents(bundleDescriptor, type, subComponentsMap); } else { // for ear case, get modules Collection<ModuleDescriptor<BundleDescriptor>> modules = getSubModuleListForEar(application, type); for (ModuleDescriptor module : modules) { StringBuffer sb = new StringBuffer(); String moduleName = module.getArchiveUri(); sb.append("<"); String moduleType = getModuleType(module); sb.append(moduleType); sb.append(">"); subComponentList.put(moduleName, sb.toString()); subComponentsMap.put(module.getArchiveUri(), moduleType); } } return subComponentList; } private Collection<ModuleDescriptor<BundleDescriptor>> getSubModuleListForEar(com.sun.enterprise.deployment.Application application, String type) { Collection<ModuleDescriptor<BundleDescriptor>> modules = new ArrayList<ModuleDescriptor<BundleDescriptor>>(); if (type == null) { modules = application.getModules(); } else if (type.equals("servlets")) { modules = application.getModuleDescriptorsByType( DOLUtils.warType()); } else if (type.equals("ejbs")) { modules = application.getModuleDescriptorsByType( DOLUtils.ejbType()); // ejb in war case Collection<ModuleDescriptor<BundleDescriptor>> webModules = application.getModuleDescriptorsByType(DOLUtils.warType()); for (ModuleDescriptor webModule : webModules) { if (webModule.getDescriptor().getExtensionsDescriptors(EjbBundleDescriptor.class).size() > 0) { modules.add(webModule); } } } return modules; } private Map<String, String> getModuleLevelComponents(BundleDescriptor bundle, String type, Map<String, String> subComponentsMap) { Map<String, String> moduleSubComponentMap = new LinkedHashMap<String, String>(); if (bundle instanceof WebBundleDescriptor) { WebBundleDescriptor wbd = (WebBundleDescriptor)bundle; // look at ejb in war case Collection<EjbBundleDescriptor> ejbBundleDescs = wbd.getExtensionsDescriptors(EjbBundleDescriptor.class); if (ejbBundleDescs.size() > 0) { EjbBundleDescriptor ejbBundle = ejbBundleDescs.iterator().next(); moduleSubComponentMap.putAll(getModuleLevelComponents( ejbBundle, type, subComponentsMap)); } if (type != null && type.equals("ejbs")) { return moduleSubComponentMap; } for (WebComponentDescriptor wcd : wbd.getWebComponentDescriptors()) { StringBuffer sb = new StringBuffer(); String canonicalName = wcd.getCanonicalName(); sb.append("<"); String wcdType = (wcd.isServlet() ? "Servlet" : "JSP"); sb.append(wcdType); sb.append(">"); moduleSubComponentMap.put(canonicalName, sb.toString()); subComponentsMap.put(wcd.getCanonicalName(), wcdType); } } else if (bundle instanceof EjbBundleDescriptor) { if (type != null && type.equals("servlets")) { return moduleSubComponentMap; } EjbBundleDescriptor ebd = (EjbBundleDescriptor)bundle; for (EjbDescriptor ejbDesc : ebd.getEjbs()) { StringBuffer sb = new StringBuffer(); String ejbName = ejbDesc.getName(); sb.append("<"); String ejbType = ejbDesc.getEjbTypeForDisplay(); sb.append(ejbType); sb.append(">"); moduleSubComponentMap.put(ejbName, sb.toString()); subComponentsMap.put(ejbDesc.getName(), ejbType); } } return moduleSubComponentMap; } private String getModuleType(ModuleDescriptor modDesc) { String type = null; if (modDesc.getModuleType().equals(DOLUtils.ejbType())) { type = "EJBModule"; } else if (modDesc.getModuleType().equals(DOLUtils.warType())) { type = "WebModule"; } else if (modDesc.getModuleType().equals(DOLUtils.carType())) { type = "AppClientModule"; } else if (modDesc.getModuleType().equals(DOLUtils.rarType())) { type = "ConnectorModule"; } return type; } }