/*
* Copyright 2005 by Oracle USA
* 500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A.
* All rights reserved.
*/
package javax.ide.wizard.spi;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.logging.Level;
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.ExtensionHook;
import javax.ide.extension.I18NStringVisitor;
import javax.ide.extension.IconVisitor;
import javax.ide.extension.spi.ExtensionVisitor;
import javax.ide.util.IconDescription;
import javax.ide.util.MetaClass;
/**
* Wizard information gathered from processing the wizard-hook
* section of an extension deployment descriptor. The information recorded
* here describes a new wizard and is generally given to the
* {@link javax.ide.wizard.WizardManager} for registration.
*/
public final class WizardHook extends ExtensionHook
{
public static final ElementName ELEMENT = new ElementName( MANIFEST_XMLNS,
"wizard-hook" );
private static final ElementName WIZARDS = new ElementName( MANIFEST_XMLNS,
"wizards" );
private static final ElementName WIZARD = new ElementName( MANIFEST_XMLNS,
"wizard" );
private static final ElementName WIZARD_CATEGORY = new ElementName( MANIFEST_XMLNS,
"wizard-category" );
private static final ElementName LABEL = new ElementName(
MANIFEST_XMLNS, "label" );
private static final ElementName ICONPATH = new ElementName(
MANIFEST_XMLNS, "iconpath" );
private static final ElementName TOOLTIP = new ElementName(
MANIFEST_XMLNS, "tooltip" );
private static final String KEY_WIZARD_INFO = "wizardInfo";
private static final String KEY_CATEGORY = "wizardCategory";
private ElementVisitor _wizardsVisitor = new WizardsVisitor();
private ElementVisitor _wizardVisitor = new WizardVisitor();
private ElementVisitor _labelVisitor = new LabelVisitor();
private ElementVisitor _iconpathVisitor = new IconPathVisitor();
private ElementVisitor _tooltipVisitor = new ToolTipVisitor();
private ElementVisitor _wizardCategoryVisitor = new WizardCategoryVisitor();
private final Map _wizardsByClass = new HashMap();
private final Map _categoriesById = new HashMap();
// Map from WizardCategory => List
private final Map _categoryChildren = new HashMap();
public WizardInfo getWizardInfo( String className )
{
final WizardInfo info = (WizardInfo)_wizardsByClass.get( className );
if ( info == null )
{
throw new IllegalArgumentException( "Unknown wizard class " + className );
}
return info;
}
/**
* Get the children of the specified category.
*
* @param category the category to get children of. This may be
* WizardCategory.NONE to get root items.
* @return a collection of either WizardCategory or WizardInfo instances.
*/
public Collection getChildren( WizardCategory category )
{
if ( category == null )
{
throw new NullPointerException( "Null category" );
}
return Collections.unmodifiableCollection( getCategoryChildren( category ) );
}
private Collection getCategoryChildren(WizardCategory parent)
{
Collection children = (Collection)_categoryChildren.get( parent );
if ( children == null )
{
children = new ArrayList();
_categoryChildren.put( parent, children );
}
return children;
}
public Collection /**/ getAllWizardClasses()
{
return Collections.unmodifiableCollection( _wizardsByClass.keySet() );
}
public void start( ElementStartContext context )
{
context.registerChildVisitor( WIZARDS, _wizardsVisitor );
}
private static WizardInfo getWizardInfo( ElementContext context )
{
return (WizardInfo) context.getScopeData().get( KEY_WIZARD_INFO );
}
private class WizardsVisitor extends ElementVisitor
{
public void start( ElementStartContext context )
{
context.registerChildVisitor( WIZARD, _wizardVisitor );
context.registerChildVisitor( WIZARD_CATEGORY, _wizardCategoryVisitor );
}
}
private class WizardCategoryVisitor extends ElementVisitor
{
public void start( ElementStartContext context )
{
String id = context.getAttributeValue( "id" );
if ( id == null || (id = id.trim()).length() == 0 )
{
log( context, Level.SEVERE, "Missing required 'id' attribute." );
return;
}
WizardCategory parent = WizardCategory.NONE;
String parentCategory = context.getAttributeValue( "parent-category" );
if ( parentCategory != null )
{
parentCategory = parentCategory.trim();
parent = (WizardCategory)_categoriesById.get( parentCategory );
if ( parent == null )
{
log( context, Level.WARNING, "Wizard category '"+parentCategory+"' not found." );
parent = WizardCategory.NONE;
}
}
WizardCategory cat = new WizardCategory( parent, id );
context.getScopeData().put( KEY_CATEGORY, cat );
_categoriesById.put( id, cat );
getCategoryChildren(parent).add( cat );
context.registerChildVisitor( LABEL, new I18NStringVisitor() {
protected void string(ElementContext context, String string)
{
WizardCategory c =
(WizardCategory) context.getScopeData().get( KEY_CATEGORY );
c.setLabel( string );
}
}
);
}
public void end( ElementEndContext context )
{
WizardCategory c = (WizardCategory) context.getScopeData().get( KEY_CATEGORY );
if ( c.getLabel() == null )
{
log( context, Level.WARNING, "Missing label element for category." );
c.setLabel( c.getId() );
}
}
}
private class WizardVisitor extends ElementVisitor
{
public void start( ElementStartContext context )
{
String className = context.getAttributeValue( "wizard-class" );
if ( className == null || (className = className.trim()).length() == 0 )
{
log( context, Level.SEVERE, "Missing required 'wizard-class' attribute." );
return;
}
String parentId = context.getAttributeValue( "category-ref" );
WizardCategory parent = WizardCategory.NONE;
if ( parentId != null && (parentId = parentId.trim()).length() > 0 )
{
parent = (WizardCategory)_categoriesById.get( parentId );
if ( parent == null )
{
log( context, Level.WARNING, "Unknown category id '" + parentId + "'." );
parent = WizardCategory.NONE;
}
}
MetaClass clazz = new MetaClass(
(ClassLoader) context.getScopeData().get( ExtensionVisitor.KEY_CLASSLOADER ),
className
);
WizardInfo info = new WizardInfo( clazz );
getCategoryChildren( parent ).add( info );
info.setCategory( parent );
context.getScopeData().put( KEY_WIZARD_INFO, info );
context.registerChildVisitor( LABEL, _labelVisitor );
context.registerChildVisitor( ICONPATH, _iconpathVisitor );
context.registerChildVisitor( TOOLTIP, _tooltipVisitor );
}
public void end( ElementEndContext context )
{
WizardInfo wi = getWizardInfo( context );
_wizardsByClass.put( wi.getWizardClass().getClassName(), wi );
}
}
private class LabelVisitor extends I18NStringVisitor
{
protected void string( ElementContext context, String value )
{
getWizardInfo( context ).setLabel( value );
}
}
private class IconPathVisitor extends IconVisitor
{
protected void icon( ElementContext context, IconDescription icon )
{
getWizardInfo( context ).setIcon( icon );
}
}
private class ToolTipVisitor extends I18NStringVisitor
{
protected void string( ElementContext context, String value )
{
getWizardInfo( context ).setToolTip( value );
}
}
}