/* * JBoss, Home of Professional Open Source. * Copyright 2011, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.ee.component; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.jboss.vfs.VirtualFile; /** * @author John Bailey */ public class EEApplicationDescription { //these are only written to by a single top level processor, so do not need to be synchronized private final Map<String, List<ViewInformation>> componentsByViewName = new HashMap<String, List<ViewInformation>>(); private final Map<String, List<Description>> componentsByName = new HashMap<String, List<Description>>(); //this must be synchronized for writing private final Map<String, List<MessageDestinationMapping>> messageDestinationJndiMapping = new HashMap<String, List<MessageDestinationMapping>>(); /** * Add a component to this application. * * @param description the component description * @param deploymentRoot */ public void addComponent(final ComponentDescription description, final VirtualFile deploymentRoot) { for (final ViewDescription viewDescription : description.getViews()) { List<ViewInformation> viewComponents = componentsByViewName.get(viewDescription.getViewClassName()); if (viewComponents == null) { viewComponents = new ArrayList<ViewInformation>(1); componentsByViewName.put(viewDescription.getViewClassName(), viewComponents); } viewComponents.add(new ViewInformation(viewDescription, deploymentRoot, description.getComponentName())); } List<Description> components = componentsByName.get(description.getComponentName()); if (components == null) { componentsByName.put(description.getComponentName(), components = new ArrayList<Description>(1)); } components.add(new Description(description, deploymentRoot)); } /** * Add a message destination to the application * * @param name The message destination name * @param resolvedName The resolved JNDI name * @param deploymentRoot The deployment root */ public void addMessageDestination(final String name, final String resolvedName, final VirtualFile deploymentRoot) { List<MessageDestinationMapping> components = messageDestinationJndiMapping.get(name); if (components == null) { messageDestinationJndiMapping.put(name, components = new ArrayList<MessageDestinationMapping>(1)); } components.add(new MessageDestinationMapping(resolvedName, deploymentRoot)); } /** * Get all views that have the given type in the application * * @param viewType The view type * @return All views of the given type */ public Set<ViewDescription> getComponentsForViewName(final String viewType, final VirtualFile deploymentRoot) { final List<ViewInformation> info = componentsByViewName.get(viewType); if (info == null) { return Collections.<ViewDescription>emptySet(); } final Set<ViewDescription> ret = new HashSet<ViewDescription>(); final Set<ViewDescription> currentDep = new HashSet<ViewDescription>(); for (ViewInformation i : info) { if (deploymentRoot.equals(i.deploymentRoot)) { currentDep.add(i.viewDescription); } ret.add(i.viewDescription); } if(!currentDep.isEmpty()) { return currentDep; } return ret; } /** * Get all components in the application that have the given name * * @param componentName The name of the component * @param deploymentRoot The deployment root of the component doing the lookup * @return A set of all views for the given component name and type */ public Set<ComponentDescription> getComponents(final String componentName, final VirtualFile deploymentRoot) { if (componentName.contains("#")) { final String[] parts = componentName.split("#"); String path = parts[0]; if (!path.startsWith("../")) { path = "../" + path; } final VirtualFile virtualPath = deploymentRoot.getChild(path); final String name = parts[1]; final List<Description> info = componentsByName.get(name); if (info == null) { return Collections.emptySet(); } final Set<ComponentDescription> ret = new HashSet<ComponentDescription>(); for (Description i : info) { //now we need to check the path if (virtualPath.equals(i.deploymentRoot)) { ret.add(i.componentDescription); } } return ret; } else { final List<Description> info = componentsByName.get(componentName); if (info == null) { return Collections.emptySet(); } final Set<ComponentDescription> all = new HashSet<ComponentDescription>(); final Set<ComponentDescription> thisDeployment = new HashSet<ComponentDescription>(); for (Description i : info) { all.add(i.componentDescription); if (i.deploymentRoot.equals(deploymentRoot)) { thisDeployment.add(i.componentDescription); } } //if there are multiple e if (all.size() > 1) { return thisDeployment; } return all; } } /** * Get all views in the application that have the given name and view type * * @param componentName The name of the component * @param viewName The view type * @param deploymentRoot The deployment root of the component doing the lookup * @return A set of all views for the given component name and type */ public Set<ViewDescription> getComponents(final String componentName, final String viewName, final VirtualFile deploymentRoot) { final List<ViewInformation> info = componentsByViewName.get(viewName); if (info == null) { return Collections.<ViewDescription>emptySet(); } if (componentName.contains("#")) { final String[] parts = componentName.split("#"); String path = parts[0]; if (!path.startsWith("../")) { path = "../" + path; } final VirtualFile virtualPath = deploymentRoot.getChild(path); final String name = parts[1]; final Set<ViewDescription> ret = new HashSet<ViewDescription>(); for (ViewInformation i : info) { if (i.beanName.equals(name)) { //now we need to check the path if (virtualPath.equals(i.deploymentRoot)) { ret.add(i.viewDescription); } } } return ret; } else { final Set<ViewDescription> all = new HashSet<ViewDescription>(); final Set<ViewDescription> thisDeployment = new HashSet<ViewDescription>(); for (ViewInformation i : info) { if (i.beanName.equals(componentName)) { all.add(i.viewDescription); if (i.deploymentRoot.equals(deploymentRoot)) { thisDeployment.add(i.viewDescription); } } } if (all.size() > 1) { return thisDeployment; } return all; } } /** * Resolves a message destination name into a JNDI name */ public Set<String> resolveMessageDestination(final String messageDestName, final VirtualFile deploymentRoot) { if (messageDestName.contains("#")) { final String[] parts = messageDestName.split("#"); String path = parts[0]; if (!path.startsWith("../")) { path = "../" + path; } final VirtualFile virtualPath = deploymentRoot.getChild(path); final String name = parts[1]; final Set<String> ret = new HashSet<String>(); final List<MessageDestinationMapping> data = messageDestinationJndiMapping.get(name); if (data != null) { for (final MessageDestinationMapping i : data) { //now we need to check the path if (virtualPath.equals(i.deploymentRoot)) { ret.add(i.jndiName); } } } return ret; } else { final Set<String> all = new HashSet<String>(); final Set<String> thisDeployment = new HashSet<String>(); final List<MessageDestinationMapping> data = messageDestinationJndiMapping.get(messageDestName); if (data != null) { for (final MessageDestinationMapping i : data) { all.add(i.jndiName); if (i.deploymentRoot.equals(deploymentRoot)) { thisDeployment.add(i.jndiName); } } } if (all.size() > 1) { return thisDeployment; } return all; } } private static class ViewInformation { private final ViewDescription viewDescription; private final VirtualFile deploymentRoot; private final String beanName; public ViewInformation(final ViewDescription viewDescription, final VirtualFile deploymentRoot, final String beanName) { this.viewDescription = viewDescription; this.deploymentRoot = deploymentRoot; this.beanName = beanName; } } private static class Description { private final ComponentDescription componentDescription; private final VirtualFile deploymentRoot; public Description(final ComponentDescription componentDescription, final VirtualFile deploymentRoot) { this.componentDescription = componentDescription; this.deploymentRoot = deploymentRoot; } } private static final class MessageDestinationMapping { private final String jndiName; private final VirtualFile deploymentRoot; public MessageDestinationMapping(final String jndiName, final VirtualFile deploymentRoot) { this.jndiName = jndiName; this.deploymentRoot = deploymentRoot; } } }