Source code: javax/ide/extension/spi/HookHandlerHook.java
1 package javax.ide.extension.spi;
2
3 import java.util.logging.Level;
4 import javax.ide.extension.ElementName;
5 import javax.ide.extension.ElementStartContext;
6 import javax.ide.extension.ElementVisitor;
7 import javax.ide.extension.ExtensionHook;
8
9 /**
10 * The hook-handler-hook implementation. This implementation takes a
11 * <tt>DefaultHookVisitorFactory</tt> in its constructor and registers
12 * handlers for custom hooks through this factory.
13 */
14 public class HookHandlerHook extends ExtensionHook
15 {
16 public static final ElementName ELEMENT = new ElementName(
17 MANIFEST_XMLNS, "hook-handler-hook" );
18 private final DefaultHookVisitorFactory _factory;
19
20 private final ElementName HOOKHANDLER = new ElementName(
21 MANIFEST_XMLNS, "hook-handler" );
22
23 private ElementVisitor _hookHandlerVisitor = new HookHandlerVisitor();
24
25 /**
26 * Constructs a new HookHandlerHook.
27 *
28 * @param hookFactory the hook factory. Must not be null.
29 */
30 public HookHandlerHook( DefaultHookVisitorFactory hookFactory )
31 {
32 if ( hookFactory == null )
33 {
34 throw new NullPointerException( "hookFactory is null" );
35 }
36 _factory = hookFactory;
37 }
38
39 public void start( ElementStartContext context )
40 {
41 context.registerChildVisitor( HOOKHANDLER, _hookHandlerVisitor );
42 }
43
44
45 private class HookHandlerVisitor extends ElementVisitor
46 {
47 public void start( ElementStartContext context )
48 {
49 String tagName = context.getAttributeValue( "tag-name" );
50 if ( tagName == null || ( tagName = tagName.trim()) == "" )
51 {
52 log( context, Level.SEVERE, "Missing required attribute 'tag-name'" );
53 return;
54 }
55
56 String handlerClass = context.getAttributeValue( "handler-class" );
57 if ( handlerClass == null || ( handlerClass = handlerClass.trim() ) == "" )
58 {
59 log( context, Level.SEVERE, "Missing required attribute 'handler-class'" );
60 return;
61 }
62
63 String namespace = context.getAttributeValue( "namespace" );
64 if ( namespace == null || ( namespace = namespace.trim() ) == "" )
65 {
66 log( context, Level.SEVERE, "Missing required attribute 'namespace'" );
67 return;
68 }
69
70 // Schema location is currently unused, although we should probably
71 // store it somewhere so that IDEs with design time support know where
72 // to find custom hook schemata.
73
74
75 ElementName elementName = new ElementName( namespace, tagName );
76 if ( _factory.isNameRegistered( elementName ) )
77 {
78 // For now we consider this to be an error rather than allowing
79 // handlers to be subverted by downstream extensions.
80 log( context, Level.SEVERE, "A custom hook is already registered for " +
81 elementName.getNamespaceURI()+":"+elementName.getLocalName() );
82 return;
83 }
84
85 Class hookClass;
86 try
87 {
88 hookClass = Class.forName( handlerClass, true,
89 Thread.currentThread().getContextClassLoader() );
90 }
91 catch ( ClassNotFoundException cnfe )
92 {
93 log( context, Level.SEVERE, "Custom hook class "+handlerClass+" not found." );
94 return;
95 }
96
97 try
98 {
99 ExtensionHook hook = (ExtensionHook) hookClass.newInstance();
100 _factory.registerHook( elementName, hook );
101 }
102 catch ( ClassCastException cce )
103 {
104 log( context, Level.SEVERE,
105 "Custom hook class "+hookClass.getName()+
106 " is not derived from "+ExtensionHook.class.getName()
107 );
108 }
109 catch ( InstantiationException ie )
110 {
111 log( context, Level.SEVERE,
112 "Custom hook class "+hookClass.getName()+
113 " cannot be instantiated."
114 );
115 // TODO print these to a logger or somewhere more sensible.
116 ie.printStackTrace();
117 }
118 catch ( IllegalAccessException iae )
119 {
120 log( context, Level.SEVERE,
121 "Custom hook class "+hookClass.getName()+
122 " is not public or does not have a public no argument constructor."
123 );
124 iae.printStackTrace();
125 }
126 }
127 }
128 }