You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jd...@apache.org on 2008/09/24 18:53:26 UTC
svn commit: r698648 - in
/geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src:
main/java/org/apache/geronimo/gshell/wisdom/config/
main/resources/org/apache/geronimo/gshell/wisdom/config/
test/java/org/apache/geronimo/gshell/wisdom/config/ test/...
Author: jdillon
Date: Wed Sep 24 09:53:26 2008
New Revision: 698648
URL: http://svn.apache.org/viewvc?rev=698648&view=rev
Log:
Have the basic functionality working for the spring "gshell" namespace
Added:
geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/
geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/DummyAction.java (with props)
geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/PluginParserTest.java
geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/
geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/PluginParserTest-context.xml (with props)
Modified:
geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/java/org/apache/geronimo/gshell/wisdom/config/PluginParser.java
geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/resources/org/apache/geronimo/gshell/wisdom/config/wisdom-gshell.xsd
Modified: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/java/org/apache/geronimo/gshell/wisdom/config/PluginParser.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/java/org/apache/geronimo/gshell/wisdom/config/PluginParser.java?rev=698648&r1=698647&r2=698648&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/java/org/apache/geronimo/gshell/wisdom/config/PluginParser.java (original)
+++ geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/java/org/apache/geronimo/gshell/wisdom/config/PluginParser.java Wed Sep 24 09:53:26 2008
@@ -20,13 +20,24 @@
package org.apache.geronimo.gshell.wisdom.config;
import org.apache.geronimo.gshell.wisdom.plugin.PluginImpl;
+import org.apache.geronimo.gshell.wisdom.plugin.bundle.CommandBundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Attr;
import org.w3c.dom.Element;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -37,26 +48,284 @@
public class PluginParser
extends AbstractBeanDefinitionParser
{
- protected AbstractBeanDefinition parseInternal(final Element element, final ParserContext parserContext) {
+ @Override
+ protected boolean shouldGenerateId() {
+ return true;
+ }
+
+ @Override
+ protected boolean shouldGenerateIdAsFallback() {
+ return true;
+ }
+
+ protected AbstractBeanDefinition parseInternal(final Element element, final ParserContext context) {
assert element != null;
- assert parserContext != null;
+ assert context != null;
+
+ Builder builder = new Builder(context);
+ BeanDefinitionBuilder plugin = builder.buildPlugin(element);
+ return plugin.getBeanDefinition();
+ }
- BeanDefinitionBuilder plugin = BeanDefinitionBuilder.rootBeanDefinition(PluginImpl.class);
- plugin.addPropertyValue("id", element.getAttribute("name"));
+ /**
+ * Helper to deal with command type.
+ */
+ private enum CommandType
+ {
+ STATELESS,
+ STATEFUL;
- @SuppressWarnings({"unchecked"})
- List<Element> children = DomUtils.getChildElementsByTagName(element, "command-bundle");
- if (children != null && children.size() > 0) {
- parseCommandBundles(plugin, children);
+ public static CommandType parse(final String text) {
+ assert text != null;
+
+ return valueOf(text.toUpperCase());
}
- return plugin.getBeanDefinition();
+ public String getTemplateName() {
+ return name().toLowerCase() + "CommandTemplate";
+ }
+
+ public void wire(final BeanDefinitionBuilder command, final BeanDefinitionHolder action) {
+ assert command != null;
+ assert action != null;
+
+ switch (this) {
+ case STATELESS:
+ command.addPropertyReference("action", action.getBeanName());
+ break;
+
+ case STATEFUL:
+ command.addPropertyValue("actionId", action.getBeanName());
+ break;
+ }
+ }
}
- private void parseCommandBundles(final BeanDefinitionBuilder plugin, final List<Element> elements) {
- assert elements != null;
- assert plugin != null;
+ /**
+ * Helper to build plugin related bean definitions.
+ */
+ private class Builder
+ {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private ParserContext context;
+
+ public Builder(final ParserContext context) {
+ assert context != null;
+
+ this.context = context;
+ }
+
+ private String resolveId(final Element element, final BeanDefinition def) throws BeanDefinitionStoreException {
+ assert element != null;
+ assert def != null;
+
+ if (shouldGenerateId()) {
+ return context.getReaderContext().generateBeanName(def);
+ }
+
+ String id = element.getAttribute(ID_ATTRIBUTE);
+
+ if (!StringUtils.hasText(id) && shouldGenerateIdAsFallback()) {
+ id = context.getReaderContext().generateBeanName(def);
+ }
+
+ return id;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private List<Element> getChildElements(final Element element, final String name) {
+ assert element != null;
+ assert name != null;
+
+ return DomUtils.getChildElementsByTagName(element, name);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private Element getChildElement(final Element element, final String name) {
+ assert element != null;
+ assert name != null;
+
+ List<Element> elements = DomUtils.getChildElementsByTagName(element, name);
+ if (elements != null && !elements.isEmpty()) {
+ return elements.get(0);
+ }
+ return null;
+ }
+
+ private BeanDefinitionHolder parseBeanDefinitionElement(final Element element) {
+ assert element != null;
+
+ BeanDefinitionParserDelegate parser = new BeanDefinitionParserDelegate(context.getReaderContext());
+ parser.initDefaults(element.getOwnerDocument().getDocumentElement());
+ return parser.parseBeanDefinitionElement(element);
+ }
+
+ private BeanDefinitionHolder register(final BeanDefinitionHolder holder) {
+ assert holder != null;
+
+ registerBeanDefinition(holder, context.getRegistry());
+ return holder;
+ }
+
+ private BeanDefinitionHolder register(final BeanDefinition def, final String id) {
+ assert def != null;
+ assert id != null;
+
+ BeanDefinitionHolder holder = new BeanDefinitionHolder(def, id);
+ return register(holder);
+ }
+
+ public BeanDefinitionBuilder buildPlugin(final Element element) {
+ assert element != null;
+
+ BeanDefinitionBuilder plugin = parsePlugin(element);
+
+ List<BeanDefinitionHolder> bundles = parseCommandBundles(element);
+
+ for (BeanDefinitionHolder holder : bundles) {
+ // TODO: Handle registration of the bundles?
+ }
+ return plugin;
+ }
+
+ private BeanDefinitionBuilder parsePlugin(final Element element) {
+ assert element != null;
+
+ log.info("Parse plugin; element: {}", element);
+
+ BeanDefinitionBuilder plugin = BeanDefinitionBuilder.rootBeanDefinition(PluginImpl.class);
+ plugin.addPropertyValue("id", element.getAttribute("name"));
+
+ return plugin;
+ }
+
+ private List<BeanDefinitionHolder> parseCommandBundles(final Element element) {
+ assert element != null;
+
+ log.info("Parse command bundles; element: {}", element);
+
+ List<Element> children = getChildElements(element, "command-bundle");
+ List<BeanDefinitionHolder> holders = new ArrayList<BeanDefinitionHolder>();
+
+ for (Element child : children) {
+ BeanDefinitionBuilder bundle = parseCommandBundle(child);
+
+ // Generate id and register the bean
+ AbstractBeanDefinition def = bundle.getBeanDefinition();
+ String id = resolveId(child, def);
+ BeanDefinitionHolder holder = register(def, id);
+
+ // noinspection unchecked
+ holders.add(holder);
+ }
+
+ return holders;
+ }
+
+ private BeanDefinitionBuilder parseCommandBundle(final Element element) {
+ assert element != null;
+
+ log.info("Parse command bundle; element; {}", element);
+
+ BeanDefinitionBuilder bundle = BeanDefinitionBuilder.rootBeanDefinition(CommandBundle.class);
+ bundle.addPropertyValue("id", element.getAttribute("name"));
+ bundle.setLazyInit(true);
+
+ List commands = parseCommands(element);
+ bundle.addPropertyValue("commands", commands);
+
+ return bundle;
+ }
+
+ private List parseCommands(final Element element) {
+ assert element != null;
+
+ log.info("Parse commands; element; {}", element);
+
+ List<Element> children = getChildElements(element, "command");
+ ManagedList defs = new ManagedList();
+ for (Element child : children) {
+ BeanDefinitionBuilder command = parseCommand(child);
+
+ // noinspection unchecked
+ defs.add(command.getBeanDefinition());
+ }
+
+ return defs;
+ }
+
+ private BeanDefinitionBuilder parseCommand(final Element element) {
+ assert element != null;
+
+ log.info("Parse command; element; {}", element);
+
+ CommandType type = CommandType.parse(element.getAttribute("type"));
+ BeanDefinitionBuilder command = BeanDefinitionBuilder.childBeanDefinition(type.getTemplateName());
+
+ // TODO: Currently name is pulled from the documentor, need to change that
+ // command.addPropertyValue("name", element.getAttribute("name"));
+
+ BeanDefinitionHolder action = parseCommandAction(element);
+
+ // Wire up the action based on the type
+ type.wire(command, action);
+
+ return command;
+ }
+
+ private BeanDefinitionHolder parseCommandAction(final Element element) {
+ assert element != null;
+
+ log.info("Parse command action; element; {}", element);
+
+ Attr actionAttr = element.getAttributeNode("action");
+ Element actionElement = getChildElement(element, "action");
+
+ // Validate that we only have one action
+ if (actionAttr != null && actionElement != null) {
+ throw new RuntimeException("Must specify only one action attribute or action element");
+ }
+ if (actionAttr == null && actionElement == null) {
+ throw new RuntimeException("Missing action attribute or action element");
+ }
+
+ // Construct the action
+ BeanDefinition action;
+
+ if (actionAttr != null) {
+ action = BeanDefinitionBuilder.rootBeanDefinition(actionAttr.getValue()).getBeanDefinition();
+ }
+ else {
+ // TODO: Can probably just treat the "action" element as a "bean" element?
+
+ Attr classAttr = actionElement.getAttributeNode("class");
+ Element beanElement = getChildElement(actionElement, "bean");
+
+ // Validate we only have one configuration for the action
+ if (classAttr != null && beanElement != null) {
+ throw new RuntimeException("Must specify only one class attribute or bean element");
+ }
+ if (classAttr == null && beanElement == null) {
+ throw new RuntimeException("Missing action class attribute or action bean element");
+ }
+
+ if (classAttr != null) {
+ action = BeanDefinitionBuilder.rootBeanDefinition(classAttr.getValue()).getBeanDefinition();
+ }
+ else {
+ action = parseBeanDefinitionElement(beanElement).getBeanDefinition();
+ }
+ }
+
+ // All actions are configured as prototypes
+ action.setScope("prototype");
+
+ // Generate id and register the bean
+ String id = resolveId(element, action);
+ return register(action, id);
+ }
}
}
\ No newline at end of file
Modified: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/resources/org/apache/geronimo/gshell/wisdom/config/wisdom-gshell.xsd
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/resources/org/apache/geronimo/gshell/wisdom/config/wisdom-gshell.xsd?rev=698648&r1=698647&r2=698648&view=diff
==============================================================================
--- geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/resources/org/apache/geronimo/gshell/wisdom/config/wisdom-gshell.xsd (original)
+++ geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/main/resources/org/apache/geronimo/gshell/wisdom/config/wisdom-gshell.xsd Wed Sep 24 09:53:26 2008
@@ -28,11 +28,11 @@
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
-
+
<xsd:annotation>
- <xsd:documentation><![CDATA[
+ <xsd:documentation>
Defines the configuration elements for GShell Wisdom application context support.
- ]]></xsd:documentation>
+ </xsd:documentation>
</xsd:annotation>
<xsd:element name="plugin">
@@ -74,7 +74,7 @@
<xsd:element ref="action" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
- <xsd:attribute name="type" type="xsd:string" use="optional" default="stateful">
+ <xsd:attribute name="type" use="optional" default="stateful">
<xsd:annotation>
<xsd:documentation>
The command type.
@@ -98,9 +98,9 @@
Defines a command action.
</xsd:documentation>
</xsd:annotation>
- <!--
- TODO: Allow nested beans:bean
- -->
+ <xsd:sequence>
+ <xsd:element ref="beans:bean" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
<xsd:attribute name="class" type="xsd:string" use="optional"/>
</xsd:complexType>
</xsd:element>
Added: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/DummyAction.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/DummyAction.java?rev=698648&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/DummyAction.java (added)
+++ geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/DummyAction.java Wed Sep 24 09:53:26 2008
@@ -0,0 +1,49 @@
+/*
+ * 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.geronimo.gshell.wisdom.config;
+
+import org.apache.geronimo.gshell.spring.LoggingProcessor;
+import org.apache.geronimo.gshell.spring.SpringTestSupport;
+import org.apache.geronimo.gshell.command.CommandAction;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.notification.Notification;
+
+/**
+ * ???
+ *
+ * @version $Rev$ $Date$
+ */
+public class DummyAction
+ implements CommandAction
+{
+ private String text;
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public Object execute(CommandContext context) throws Notification, Exception {
+ return null;
+ }
+}
\ No newline at end of file
Propchange: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/DummyAction.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/DummyAction.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/DummyAction.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/PluginParserTest.java
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/PluginParserTest.java?rev=698648&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/PluginParserTest.java (added)
+++ geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/java/org/apache/geronimo/gshell/wisdom/config/PluginParserTest.java Wed Sep 24 09:53:26 2008
@@ -0,0 +1,40 @@
+/*
+ * 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.geronimo.gshell.wisdom.config;
+
+import org.apache.geronimo.gshell.spring.LoggingProcessor;
+import org.apache.geronimo.gshell.spring.SpringTestSupport;
+
+/**
+ * Unit tests for the {@link LoggingProcessor} class.
+ *
+ * @version $Rev: 698145 $ $Date: 2008-09-23 18:39:31 +0700 (Tue, 23 Sep 2008) $
+ */
+public class PluginParserTest
+ extends SpringTestSupport
+{
+ public void testParser() throws Exception {
+ LoggingProcessor processor = new LoggingProcessor();
+ String xml = processor.render(applicationContext.getBeanFactory());
+ assertNotNull(xml);
+
+ System.out.println("XML:\n" + xml);
+ }
+}
\ No newline at end of file
Added: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/PluginParserTest-context.xml
URL: http://svn.apache.org/viewvc/geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/PluginParserTest-context.xml?rev=698648&view=auto
==============================================================================
--- geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/PluginParserTest-context.xml (added)
+++ geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/PluginParserTest-context.xml Wed Sep 24 09:53:26 2008
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:gshell="http://gshell.org/schema/wisdom-gshell"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://gshell.org/schema/wisdom-gshell http://gshell.org/schema/wisdom-gshell/wisdom-gshell.xsd">
+
+ <gshell:plugin name="test-plugin">
+ <gshell:command-bundle name="test">
+ <gshell:command name="a" action="org.apache.geronimo.gshell.commands.SomeAction"/>
+
+ <gshell:command name="b" type="stateless" action="org.apache.geronimo.gshell.commands.SomeAction"/>
+
+ <gshell:command name="c" type="stateful" action="org.apache.geronimo.gshell.commands.SomeAction"/>
+
+ <gshell:command name="d">
+ <gshell:action>
+ <bean class="org.apache.geronimo.gshell.wisdom.config.DummyAction">
+ <property name="text" value="b"/>
+ </bean>
+ </gshell:action>
+ </gshell:command>
+
+ <gshell:command name="e">
+ <gshell:action class="org.apache.geronimo.gshell.wisdom.config.DummyAction"/>
+ </gshell:command>
+ </gshell:command-bundle>
+ </gshell:plugin>
+
+</beans>
\ No newline at end of file
Propchange: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/PluginParserTest-context.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/PluginParserTest-context.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: geronimo/gshell/trunk/gshell-wisdom/gshell-wisdom-core/src/test/resources/org/apache/geronimo/gshell/wisdom/config/PluginParserTest-context.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml