/* * 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.apache.karaf.obr.core.internal; import java.util.ArrayList; import java.util.List; import javax.management.MBeanException; import javax.management.NotCompliantMBeanException; import javax.management.StandardMBean; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; import org.apache.felix.bundlerepository.Repository; import org.apache.felix.bundlerepository.RepositoryAdmin; import org.apache.felix.bundlerepository.Resolver; import org.apache.felix.bundlerepository.Resource; import org.apache.karaf.obr.core.ObrMBean; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.Version; /** * Implementation of the OBR MBean. */ public class ObrMBeanImpl extends StandardMBean implements ObrMBean { private static final char VERSION_DELIM = ','; private BundleContext bundleContext; private RepositoryAdmin repositoryAdmin; public ObrMBeanImpl(BundleContext bundleContext, RepositoryAdmin repositoryAdmin) throws NotCompliantMBeanException { super(ObrMBean.class); this.bundleContext = bundleContext; this.repositoryAdmin = repositoryAdmin; } public List<String> getUrls() { Repository[] repositories = repositoryAdmin.listRepositories(); List<String> urls = new ArrayList<String>(); for (int i = 0; i < repositories.length; i++) { urls.add(repositories[i].getURI()); } return urls; } public TabularData getBundles() throws MBeanException { try { CompositeType bundleType = new CompositeType("OBR Resource", "Bundle available in the OBR", new String[]{"presentationname", "symbolicname", "version"}, new String[]{"Presentation Name", "Symbolic Name", "Version"}, new OpenType[]{SimpleType.STRING, SimpleType.STRING, SimpleType.STRING}); TabularType tableType = new TabularType("OBR Resources", "Table of all resources/bundles available in the OBR", bundleType, new String[]{"symbolicname", "version"}); TabularData table = new TabularDataSupport(tableType); Resource[] resources = repositoryAdmin.discoverResources("(|(presentationname=*)(symbolicname=*))"); for (int i = 0; i < resources.length; i++) { try { CompositeData data = new CompositeDataSupport(bundleType, new String[]{"presentationname", "symbolicname", "version"}, new Object[]{resources[i].getPresentationName(), resources[i].getSymbolicName(), resources[i].getVersion().toString()}); table.put(data); } catch (Exception e) { e.printStackTrace(); } } return table; } catch (Exception e) { throw new MBeanException(null, e.toString()); } } public void addUrl(String url) throws MBeanException { try { repositoryAdmin.addRepository(url); } catch (Exception e) { throw new MBeanException(null, e.toString()); } } public void removeUrl(String url) { repositoryAdmin.removeRepository(url); } public void refreshUrl(String url) throws MBeanException { try { repositoryAdmin.addRepository(url); } catch (Exception e) { throw new MBeanException(null, e.toString()); } } public void deployBundle(String bundle) throws MBeanException { try { deployBundle(bundle, false, false); } catch (Exception e) { throw new MBeanException(null, e.toString()); } } public void deployBundle(String bundle, boolean start, boolean deployOptional) throws MBeanException { try { Resolver resolver = repositoryAdmin.resolver(); String[] target = getTarget(bundle); Resource resource = selectNewestVersion(searchRepository(repositoryAdmin, target[0], target[1])); if (resource == null) { throw new IllegalArgumentException("Unknown bundle " + target[0]); } resolver.add(resource); if ((resolver.getAddedResources() != null) && (resolver.getAddedResources().length > 0)) { if (resolver.resolve(deployOptional ? 0 : Resolver.NO_OPTIONAL_RESOURCES)) { try { resolver.deploy(start ? Resolver.START : 0); } catch (IllegalStateException ex) { throw new IllegalStateException("Can't deploy using OBR", ex); } } } } catch (Exception e) { throw new MBeanException(null, e.toString()); } } private Resource[] searchRepository(RepositoryAdmin admin, String targetId, String targetVersion) throws InvalidSyntaxException { // Try to see if the targetId is a bundle ID. try { Bundle bundle = bundleContext.getBundle(Long.parseLong(targetId)); targetId = bundle.getSymbolicName(); } catch (NumberFormatException ex) { // It was not a number, so ignore. } // The targetId may be a bundle name or a bundle symbolic name, // so create the appropriate LDAP query. StringBuffer sb = new StringBuffer("(|(presentationname="); sb.append(targetId); sb.append(")(symbolicname="); sb.append(targetId); sb.append("))"); if (targetVersion != null) { sb.insert(0, "(&"); sb.append("(version="); sb.append(targetVersion); sb.append("))"); } return admin.discoverResources(sb.toString()); } private Resource selectNewestVersion(Resource[] resources) { int idx = -1; Version v = null; for (int i = 0; (resources != null) && (i < resources.length); i++) { if (i == 0) { idx = 0; v = resources[i].getVersion(); } else { Version vtmp = resources[i].getVersion(); if (vtmp.compareTo(v) > 0) { idx = i; v = vtmp; } } } return (idx < 0) ? null : resources[idx]; } private String[] getTarget(String bundle) { String[] target; int idx = bundle.indexOf(VERSION_DELIM); if (idx > 0) { target = new String[]{bundle.substring(0, idx), bundle.substring(idx + 1)}; } else { target = new String[]{bundle, null}; } return target; } }