notify-dpml AT lists.ibiblio.org
Subject: DPML Notify
List archive
r1941 - in trunk/main/metro/part: etc/data etc/xsds src/main/net/dpml/runtime src/test/net/dpml/runtime/context src/test/org/acme
- From: mcconnell at BerliOS <mcconnell AT mail.berlios.de>
- To: notify-dpml AT lists.ibiblio.org
- Subject: r1941 - in trunk/main/metro/part: etc/data etc/xsds src/main/net/dpml/runtime src/test/net/dpml/runtime/context src/test/org/acme
- Date: Mon, 2 Apr 2007 18:51:03 +0200
Author: mcconnell
Date: 2007-04-02 18:50:55 +0200 (Mon, 02 Apr 2007)
New Revision: 1941
Added:
trunk/main/metro/part/etc/data/map.xml
trunk/main/metro/part/src/test/net/dpml/runtime/context/MapTestCase.java
trunk/main/metro/part/src/test/org/acme/MapWidget.java
Modified:
trunk/main/metro/part/etc/xsds/component.xsd
trunk/main/metro/part/src/main/net/dpml/runtime/ContextDirective.java
Log:
add support for Map<String,Object> datatypes into the context model
Added: trunk/main/metro/part/etc/data/map.xml
===================================================================
--- trunk/main/metro/part/etc/data/map.xml 2007-04-01 06:25:18 UTC (rev
1940)
+++ trunk/main/metro/part/etc/data/map.xml 2007-04-02 16:50:55 UTC (rev
1941)
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<part xmlns="dpml:part">
+
+ <component xmlns="dpml:metro"
+ name="widget"
+ class="org.acme.MapWidget">
+ <context>
+ <map key="demo">
+ <entry key="message" value="Hello from the map entry"/>
+ <entry key="foo" value="bar"/>
+ </map>
+ </context>
+ </component>
+
+</part>
Modified: trunk/main/metro/part/etc/xsds/component.xsd
===================================================================
--- trunk/main/metro/part/etc/xsds/component.xsd 2007-04-01 06:25:18
UTC (rev 1940)
+++ trunk/main/metro/part/etc/xsds/component.xsd 2007-04-02 16:50:55
UTC (rev 1941)
@@ -13,6 +13,7 @@
<element name="categories" type="this:CategoriesType"
substitutionGroup="this:category"/>
<element name="entry" type="this:EntryType"/>
<element name="context" type="this:ContextEntryType"
substitutionGroup="this:entry"/>
+ <element name="map" type="this:MapEntryType"
substitutionGroup="this:entry"/>
<element name="param" type="part:ValueType"
substitutionGroup="part:param"/>
<element name="profile" type="this:ProfileType"/>
<element name="parts" type="this:PartsType"/>
@@ -97,6 +98,12 @@
</complexContent>
</complexType>
+ <complexType name="MapEntryType">
+ <complexContent>
+ <extension base="this:EntryType"/>
+ </complexContent>
+ </complexType>
+
<complexType name="PartsType">
<sequence>
<element ref="part:strategy" minOccurs="0" maxOccurs="unbounded"/>
Modified:
trunk/main/metro/part/src/main/net/dpml/runtime/ContextDirective.java
===================================================================
--- trunk/main/metro/part/src/main/net/dpml/runtime/ContextDirective.java
2007-04-01 06:25:18 UTC (rev 1940)
+++ trunk/main/metro/part/src/main/net/dpml/runtime/ContextDirective.java
2007-04-02 16:50:55 UTC (rev 1941)
@@ -77,14 +77,8 @@
"Context entry does not declare a key.";
throw new DecodingException( error, null, child );
}
-
- if( "context".equals( child.getLocalName() ) )
+ if( "entry".equals( child.getLocalName() ) )
{
- ContextDirective directive = new ContextDirective(
classloader, child, resolver );
- m_entries.put( key, directive );
- }
- else if( "entry".equals( child.getLocalName() ) )
- {
String service = ElementHelper.getAttribute( child,
"lookup" );
if( null == service )
{
@@ -98,6 +92,17 @@
m_entries.put( key, loookup );
}
}
+ else if( "context".equals( child.getLocalName() ) )
+ {
+ ContextDirective directive = new ContextDirective(
classloader, child, resolver );
+ m_entries.put( key, directive );
+ }
+ else if( "map".equals( child.getLocalName() ) )
+ {
+ Map<String,Value> map = buildMapValue( child, resolver );
+ MapWrapper wrapper = new MapWrapper( child, map );
+ m_entries.put( key, wrapper );
+ }
else
{
final String error =
@@ -108,6 +113,25 @@
}
}
+ private Map<String,Value> buildMapValue( Element element, Resolver
resolver ) throws ComponentException
+ {
+ Map<String,Value> map = new Hashtable<String,Value>();
+ Element[] elements = ElementHelper.getChildren( element );
+ for( Element elem : elements )
+ {
+ String key = ElementHelper.getAttribute( elem, "key", null,
resolver );
+ if( null == key )
+ {
+ final String error =
+ "Map entry does not declare a key.";
+ throw new ComponentException( error, null, elem );
+ }
+ Value value = VALUE_DECODER.decodeValue( elem, resolver );
+ map.put( key, value );
+ }
+ return map;
+ }
+
int size()
{
return m_entries.size();
@@ -206,6 +230,41 @@
}
}
+ static class MapWrapper extends AbstractResolvable
+ {
+ private final Map<String,Value> m_values;
+
+ MapWrapper( Element element, Map<String,Value> values )
+ {
+ super( element );
+ m_values = values;
+ }
+
+ public <T>T resolve( ComponentStrategy parent, Class<T> type )
throws Exception
+ {
+ Map<String,Object> map = new Hashtable<String,Object>();
+
+ for( String k : m_values.keySet() )
+ {
+ Value v = m_values.get( k );
+ Object o = v.resolve( parent.getContextMap() );
+ map.put( k, o );
+ }
+ return type.cast( map );
+ }
+
+ public void encode( Buffer buffer, String key ) throws IOException
+ {
+ buffer.nl( "<map key=\"" + key + "\">" );
+ for( String k : m_values.keySet() )
+ {
+ Value v = m_values.get( k );
+ v.encode( buffer, "entry", k );
+ }
+ buffer.nl( "</map>" );
+ }
+ }
+
static class Lookup extends AbstractResolvable
{
private final Class m_class;
Added:
trunk/main/metro/part/src/test/net/dpml/runtime/context/MapTestCase.java
===================================================================
--- trunk/main/metro/part/src/test/net/dpml/runtime/context/MapTestCase.java
2007-04-01 06:25:18 UTC (rev 1940)
+++ trunk/main/metro/part/src/test/net/dpml/runtime/context/MapTestCase.java
2007-04-02 16:50:55 UTC (rev 1941)
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2006 Stephen J. McConnell.
+ *
+ * Licensed 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 net.dpml.runtime.context;
+
+import java.util.Map;
+
+import net.dpml.runtime.AbstractTestCase;
+
+import org.acme.MapWidget;
+import org.acme.Widget;
+
+/**
+ *
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public class MapTestCase extends AbstractTestCase
+{
+ public void testEquality() throws Exception
+ {
+ MapWidget widget =
+ load( MapWidget.class, "map.xml", "map" );
+ Map map = widget.getContext().getDemo();
+ int n = map.size();
+ String message = (String) map.get( "message" );
+ String value = (String) map.get( "foo" );
+
+ assertEquals( "message", "Hello from the map entry", message );
+ assertEquals( "foo", "bar", value );
+ }
+}
Added: trunk/main/metro/part/src/test/org/acme/MapWidget.java
===================================================================
--- trunk/main/metro/part/src/test/org/acme/MapWidget.java 2007-04-01
06:25:18 UTC (rev 1940)
+++ trunk/main/metro/part/src/test/org/acme/MapWidget.java 2007-04-02
16:50:55 UTC (rev 1941)
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2004-2006 Stephen J. McConnell.
+ *
+ * Licensed 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.acme;
+
+import java.util.Map;
+
+import net.dpml.util.Logger;
+
+/**
+ * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
+ * @version @PROJECT-VERSION@
+ */
+public class MapWidget implements Widget
+{
+ public interface Context
+ {
+ Map getDemo();
+ }
+
+ private Context m_context;
+
+ public MapWidget( Logger logger, Context context )
+ {
+ m_context = context;
+ logger.info( "" + getMessage() );
+ }
+
+ public String getMessage()
+ {
+ Object message = m_context.getDemo().get( "message" );
+ if( null != message )
+ {
+ return message.toString();
+ }
+ return null;
+ }
+
+ public Context getContext()
+ {
+ return m_context;
+ }
+
+ public boolean equals( Object other )
+ {
+ return ( hashCode() == other.hashCode() );
+ }
+}
- r1941 - in trunk/main/metro/part: etc/data etc/xsds src/main/net/dpml/runtime src/test/net/dpml/runtime/context src/test/org/acme, mcconnell at BerliOS, 04/02/2007
Archive powered by MHonArc 2.6.24.