/* * Copyright 2005 by Oracle USA * 500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A. * All rights reserved. */ package javax.ide.extension.spi; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import javax.ide.extension.ElementContext; import javax.ide.extension.ElementEndContext; import javax.ide.extension.ElementName; import javax.ide.extension.ElementStartContext; import javax.ide.extension.ElementVisitor; import javax.ide.extension.ElementVisitorFactory; import javax.ide.extension.Extension; import javax.ide.extension.ExtensionHook; /** * Visitor for the root JSR-198 extension element. This is the "entry point" * for all manifest processing. */ public abstract class ExtensionVisitor extends BaseExtensionVisitor { private static final ElementName NAME = new ElementName( ExtensionHook.MANIFEST_XMLNS, "name" ); private static final ElementName OWNER = new ElementName( ExtensionHook.MANIFEST_XMLNS, "owner" ); private static final ElementName CLASSPATHS = new ElementName( ExtensionHook.MANIFEST_XMLNS, "classpaths" ); private ElementVisitor _nameVisitor = createNameVisitor(); private ElementVisitor _ownerVisitor = createOwnerVisitor(); private ElementVisitor _classpathsVisitor = createClasspathsVisitor(); private ElementVisitor _dependenciesVisitor = createDependenciesVisitor(); /** * The key for the ClassLoader to be used to when looking up classes * for the current extension. This is used by I18NStringVisitor / * I18NCharVisitor. If no classloader is in the scope map, the context * classloader of the current thread is used. */ public static final String KEY_CLASSLOADER = "classLoader"; private static final String KEY_LOOKUP_DONE = "lookupDone"; private static final String KEY_LAST_RSKEY = "lastRSKey"; private Map _extensionsById = new LinkedHashMap(); protected ExtensionVisitor( ElementVisitorFactory hookFactory ) { setHookVisitorFactory( hookFactory ); } /** * Returns the extension with the specified id. * * @param id the id to look up * @return the extension with the specified id, or null. * @since 2.0 */ public final Extension findExtension( String id ) { return _extensionsById.get( id ); } public final Collection getExtensions() { return _extensionsById.values(); } public final void start( ElementStartContext context ) { Extension ext = processExtension( context ); if ( ext == null ) { return; } context.getScopeData().put( ExtensionVisitor.KEY_CLASSLOADER, getClassLoader( ext ) ); String rsbundleClass = context.getAttributeValue( "rsbundle-class" ); if ( rsbundleClass != null && ( rsbundleClass = rsbundleClass.trim()) != "" ) { context.getScopeData().put( ExtensionHook.KEY_RSBUNDLE_CLASS, rsbundleClass ); } context.registerChildVisitor( NAME, _nameVisitor ); context.registerChildVisitor( OWNER, _ownerVisitor ); context.registerChildVisitor( CLASSPATHS, _classpathsVisitor ); context.registerChildVisitor( DependenciesVisitor.ELEMENT, _dependenciesVisitor ); context.getScopeData().put( KEY_LOOKUP_DONE, false ); } public void extension( ElementContext context, Extension extension ) { _extensionsById.put( extension.getID(), extension ); } protected ElementVisitor createNameVisitor() { return new ElementVisitor() { public void start( ElementStartContext context ) { String rsKey = context.getAttributeValue( "rskey" ); if ( rsKey == "" ) rsKey = null; context.getScopeData().put( KEY_LAST_RSKEY, rsKey ); } public void end( ElementEndContext context ) { DefaultExtension extension = getExtension( context ); String rsKey = (String) context.getScopeData().get( KEY_LAST_RSKEY ); if ( rsKey != null ) { extension.setRawName( "${" + rsKey + "}" ); } else { DefaultElementContext dec = (DefaultElementContext) context; extension.setRawName( dec.getRawText() ); } } }; } protected ElementVisitor createOwnerVisitor() { return new ElementVisitor() { public void start( ElementStartContext context ) { String rsKey = context.getAttributeValue( "rskey" ); if ( rsKey == "" ) rsKey = null; context.getScopeData().put( KEY_LAST_RSKEY, rsKey ); } public void end( ElementEndContext context ) { DefaultExtension extension = getExtension( context ); String rsKey = (String) context.getScopeData().get( KEY_LAST_RSKEY ); if ( rsKey != null ) { extension.setRawOwner( "${" + rsKey + "}" ); } else { DefaultElementContext dec = (DefaultElementContext) context; extension.setRawOwner( dec.getRawText() ); } } }; } protected ElementVisitor createClasspathsVisitor() { return new ClasspathsVisitor(); } protected ElementVisitor createDependenciesVisitor() { return new DependenciesVisitor(); } /** * Get the class loader that should be used by default to load an * extension.

* * This implementation returns Thread.currentThread().getContextClassLoader(). * * @param extension the extension being processed. * @return the classloader to use to load resources for the specified * extension. */ protected ClassLoader getClassLoader( Extension extension ) { return Thread.currentThread().getContextClassLoader(); } protected final void addExtensionSourceToClasspath( ElementContext context ) { super.addExtensionSourceToClasspath( context ); Boolean done = (Boolean)context.getScopeData().get( KEY_LOOKUP_DONE ); if ( done == null || !done.booleanValue() ) { context.getScopeData().put( KEY_LOOKUP_DONE, true ); Extension extension = getExtension( context ); if ( extension instanceof DefaultExtension && context instanceof DefaultElementContext ) { DefaultElementContext dContext = (DefaultElementContext) context; DefaultExtension de = (DefaultExtension) extension; de.setName( dContext.getProcessedText( de.getRawName() ) ); de.setOwner( dContext.getProcessedText( de.getRawOwner() ) ); } } } }