/******************************************************************************* * Copyright (c) 2008, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware Inc. - initial contribution *******************************************************************************/ package org.eclipse.virgo.shell.internal.completers; import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.eclipse.virgo.repository.management.ArtifactDescriptorSummary; import org.eclipse.virgo.repository.management.RepositoryInfo; import org.eclipse.virgo.shell.CommandCompleter; public class InstallCompleter implements CommandCompleter { private static final String FILE_PREFIX = "file:"; private static final String FILE_PATH_CANDIDATE_FORMAT = FILE_PREFIX + "%s%s"; private static final String REPOSITORY_PREFIX = "repository:"; private static final String REPOSITORY_TYPE_NAME_VERSION_FORMAT = REPOSITORY_PREFIX + "%s/%s/%s"; private static final String REPOSITORY_TYPE_NAME_FORMAT = REPOSITORY_PREFIX + "%s/%s/"; private static final String REPOSITORY_TYPE_FORMAT = REPOSITORY_PREFIX + "%s/"; private static final String[] SCHEMES = { FILE_PREFIX, REPOSITORY_PREFIX }; private final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); private final ObjectName repositoryQuery; private final ObjectName hostedRepositoryQuery; public InstallCompleter() throws MalformedObjectNameException, NullPointerException { this.repositoryQuery = new ObjectName("org.eclipse.virgo.kernel:type=Repository,*"); this.hostedRepositoryQuery = new ObjectName("org.eclipse.virgo.server:type=HostedRepository,*"); } public List<String> getCompletionCandidates(String subcommand, String... arguments) { Set<String> candidates; if (arguments.length == 0) { if (subcommand.startsWith(REPOSITORY_PREFIX)) { candidates = repository(subcommand); } else if (subcommand.startsWith(FILE_PREFIX)) { candidates = file(subcommand); } else { candidates = new HashSet<String>(); for (String scheme : SCHEMES) { if (scheme.startsWith(subcommand)) { candidates.add(scheme); } } } } else { // We do not complete anything after the 'subcommand' argument candidates = new HashSet<String>(); } List<String> candidateList = new ArrayList<String>(candidates); Collections.sort(candidateList); return candidateList; } private Set<String> file(String subcommand) { List<String> candidates = new ArrayList<String>(); String path = subcommand.substring(FILE_PREFIX.length()); int completionIndex = 0; //new FileNameCompletor().complete(path, path.length(), candidates); Set<String> candidateSet = new HashSet<String>(candidates.size()); if (completionIndex >= 0) { String completablePath = path.substring(0, completionIndex); for (String candidate : candidates) { candidateSet.add(String.format(FILE_PATH_CANDIDATE_FORMAT, completablePath, candidate)); } } return candidateSet; } private Set<String> repository(String subcommand) { List<String> uriParts = getUriParts(subcommand); if (uriParts.size() == 1) { return type(uriParts.get(0)); } else if (uriParts.size() == 2) { return name(uriParts.get(0), uriParts.get(1)); } else if (uriParts.size() == 3) { return version(uriParts.get(0), uriParts.get(1), uriParts.get(2)); } return Collections.emptySet(); } private List<String> getUriParts(String subcommand) { List<String> uriParts = new ArrayList<String>(Arrays.asList(subcommand.substring(REPOSITORY_PREFIX.length()).split("/"))); if (subcommand.endsWith("/")) { uriParts.add(""); } return uriParts; } private Set<String> type(String type) { Set<String> types = new HashSet<String>(); for (RepositoryInfo repository : getRepositories()) { for (ArtifactDescriptorSummary artifact : repository.getAllArtifactDescriptorSummaries()) { if (artifact.getType().startsWith(type)) { types.add(String.format(REPOSITORY_TYPE_FORMAT, artifact.getType())); } } } return types; } private Set<String> name(String type, String name) { Set<String> names = new HashSet<String>(); for (RepositoryInfo repository : getRepositories()) { for (ArtifactDescriptorSummary artifact : repository.getAllArtifactDescriptorSummaries()) { if (artifact.getType().equals(type) && artifact.getName().startsWith(name)) { names.add(String.format(REPOSITORY_TYPE_NAME_FORMAT, artifact.getType(), artifact.getName())); } } } return names; } private Set<String> version(String type, String name, String version) { Set<String> versions = new HashSet<String>(); for (RepositoryInfo repository : getRepositories()) { for (ArtifactDescriptorSummary artifact : repository.getAllArtifactDescriptorSummaries()) { if (artifact.getType().equals(type) && artifact.getName().equals(name) && artifact.getVersion().startsWith(version)) { versions.add(String.format(REPOSITORY_TYPE_NAME_VERSION_FORMAT, artifact.getType(), artifact.getName(), artifact.getVersion())); } } } return versions; } private Set<RepositoryInfo> getRepositories() { Set<String> hostedRepositoryNames = new HashSet<String>(); for (ObjectName objectName : this.server.queryNames(this.hostedRepositoryQuery, null)) { hostedRepositoryNames.add(objectName.getKeyProperty("name")); } Set<RepositoryInfo> repositories = new HashSet<RepositoryInfo>(); for (ObjectName objectName : this.server.queryNames(this.repositoryQuery, null)) { String name = objectName.getKeyProperty("name"); if (!hostedRepositoryNames.contains(name)) { repositories.add(JMX.newMXBeanProxy(this.server, objectName, RepositoryInfo.class)); } } return repositories; } }