/* * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * 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: * bstefanescu */ package org.eclipse.ecr.web.jaxrs; import java.lang.reflect.Array; import java.util.ArrayList; import org.osgi.framework.Bundle; /** * Some helper methods for parsing configuration and loading contributed servlets or filters. * * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> * */ public class Utils { /** * Load classes from a list of class references given as a comma separated string list. * * @param classRefs the string containing the list of class references * @return an array of the loaded classes * @throws ClassNotFoundException * @throws BundleNotFoundException */ public static Class<?>[] loadClasses(String classRefs) throws ClassNotFoundException, BundleNotFoundException { return loadClasses(classRefs, ','); } /** * Load classes from a list of class references given as a 'sep' separated string list. * * @param classRefs the string containing the list of class references * @param sep the separator character used to separate class references in the string. * @return an array of the loaded classes * * @throws ClassNotFoundException * @throws BundleNotFoundException */ public static Class<?>[] loadClasses(String classRefs, char sep) throws ClassNotFoundException, BundleNotFoundException { StringBuilder buf = null; ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); char[] chars = classRefs.toCharArray(); for (int i=0; i<chars.length; i++) { char c = chars[i]; if (c <= ' ') { continue; } else if (c == sep) { if (buf != null) { classes.add(loadClass(buf.toString())); buf = null; } } else { if (buf == null) { buf = new StringBuilder(); } buf.append(c); } } if (buf != null) { classes.add(loadClass(buf.toString())); } return classes.toArray(new Class<?>[classes.size()]); } /** * Get class instances for the given class references string * @param <T> * @param componentType the type of the expected array component * @param classRefs * @return * @throws Exception * * @see {@link #loadClasses(String)} */ public static <T> T[] newInstances(Class<T> componentType, String classRefs) throws Exception { return newInstances(componentType, classRefs, ','); } /** * Get class instances for the given class references string * @param <T> * @param componentType * @param classRefs * @param sep * @return * @throws Exception * * @see {@link #loadClasses(String, char)} */ @SuppressWarnings("unchecked") public static <T> T[] newInstances(Class<T> componentType, String classRefs, char sep) throws Exception { Class<?>[] classes = loadClasses(classRefs, sep); T[] ar = (T[])Array.newInstance(componentType, classes.length); for (int i=0; i<classes.length; i++) { ar[i] = (T)classes[i].newInstance(); } return ar; } /** * Load a class from a class reference string. The class reference string is in the format: * <code>bundleSymbolicName:className</code> or <code>className</code>. * If no bundle symbolic name is given the class will be loaded using the class loader of the {@link Utils} class. * <p> * The bundle will be resolved to the last version of the bundle * (in case when different bundle versions are found) * * @param classRef * @return * @throws ClassNotFoundException * @throws BundleNotFoundException */ public static Class<?> loadClass(String classRef) throws ClassNotFoundException, BundleNotFoundException { int i = classRef.indexOf(':'); if (i == -1) { // use the current bundle class loader return Activator.getInstance().getContext().getBundle().loadClass(classRef.trim()); } else { return loadClass(classRef.substring(0, i).trim(), classRef.substring(i+1).trim()); } } /** * Get a class proxy reference for the given class reference * @param classRef * @return * @throws Exception */ public static ClassRef getClassRef(String classRef) throws ClassNotFoundException, BundleNotFoundException { return getClassRef(classRef, null); } public static ClassRef getClassRef(String classRef, Bundle bundle) throws ClassNotFoundException, BundleNotFoundException { int i = classRef.indexOf(':'); if (i == -1) { // use the current bundle class loader if (bundle == null) { bundle = Activator.getInstance().getContext().getBundle(); } return new ClassRef(bundle, bundle.loadClass(classRef.trim())); } else { String bundleId = classRef.substring(0, i).trim(); String className = classRef.substring(i+1).trim(); Bundle[] bundles = Activator.getInstance().getPackageAdmin().getBundles(bundleId, null); if (bundles != null) { return new ClassRef(bundles[0], bundles[0].loadClass(className)); } else { throw new BundleNotFoundException(bundleId); } } } /** * Load a class given the owner bundle and the class name. * <p> * The bundle will be resolved to the last version of the bundle * (in case when different bundle versions are found) * * @param bundleId * @param className * @return * @throws ClassNotFoundException * @throws BundleNotFoundException */ public static Class<?> loadClass(String bundleId, String className) throws ClassNotFoundException, BundleNotFoundException { Bundle[] bundles = Activator.getInstance().getPackageAdmin().getBundles(bundleId, null); if (bundles != null) { return bundles[0].loadClass(className); } else { throw new BundleNotFoundException(bundleId); } } /** * Create a new object of the given class in the given bundle. The class should provide a no-args empty constructor. * <p> * The bundle will be resolved to the last version of the bundle * (in case when different bundle versions are found) * * @param bundleId * @param className * @return * @throws Exception * * @see {@link #loadClass(String, String)} */ public static Object newInstance(String bundleId, String className) throws Exception { return loadClass(bundleId, className).newInstance(); } /** * Create a new object of the given a class reference. * <p> * The bundle will be resolved to the last version of the bundle * (in case when different bundle versions are found) * * @param classRef * @return * @throws Exception * * @see {@link #loadClass(String, String)} */ public static Object newInstance(String classRef) throws Exception { return loadClass(classRef).newInstance(); } public static class ClassRef { protected Bundle bundle; protected Class<?> clazz; public ClassRef(Bundle bundle, Class<?> clazz) { this.bundle = bundle; this.clazz = clazz; } public Class<?> get() { return clazz; } public Bundle bundle() { return bundle; } public Object newInstance() throws Exception { return clazz.newInstance(); } @Override public String toString() { if (bundle != null) { return bundle.getSymbolicName()+":"+clazz.getName(); } return clazz.getName(); } } }