[java-identity-provider] branch master updated: Add inline/resource scripting to EntityAttributes metadata filter.

Scott Cantor cantor.2 at osu.edu
Tue May 9 14:15:28 EDT 2017


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch master
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=77901b29910394cfa185ca3e598c958bc97a36c1

The following commit(s) were added to refs/heads/master by this push:
       new  77901b2   Add inline/resource scripting to EntityAttributes metadata filter.
77901b2 is described below

commit 77901b29910394cfa185ca3e598c958bc97a36c1
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue May 9 14:15:14 2017 -0400

    Add inline/resource scripting to EntityAttributes metadata filter.
---
 .../metadata/ScriptTypeBeanParser.java             |  84 ++++++++++++++
 .../filter/impl/EntityAttributesFilterParser.java  |  29 ++++-
 .../metadata/AbstractMetadataParserTest.java       |   6 +-
 .../filter/EntityAttributesFilterParserTest.java   |  18 ++-
 .../metadata/filter/entityAttributes.xml           |   3 +-
 .../entityAttributesAttributeFilterScript.js       |   2 +
 .../filter/entityAttributesConditionScript.js      |   2 +
 ...tributes.xml => entityAttributesWithScript.xml} |   9 +-
 ....xml => entityAttributesWithScriptResource.xml} |   9 +-
 .../main/resources/schema/shibboleth-metadata.xsd  | 124 +++++++++++++++------
 10 files changed, 238 insertions(+), 48 deletions(-)

diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/ScriptTypeBeanParser.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/ScriptTypeBeanParser.java
new file mode 100644
index 0000000..42963e3
--- /dev/null
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/ScriptTypeBeanParser.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.idp.profile.spring.relyingparty.metadata;
+
+
+import javax.annotation.Nonnull;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.w3c.dom.Element;
+
+/**
+ * Parser for elements derived from ScriptType in the <code>urn:mace:shibboleth:2.0:metadata</code> namespace.
+ * 
+ * <p>The actual bean type is a runtime class so that different objects adhering to the general factory
+ * contracts used with scripted beans will work.</p>
+ */
+public final class ScriptTypeBeanParser {
+
+    /** Namespace for Metadata. */
+    @Nonnull @NotEmpty public static final String METADATA_NAMESPACE = "urn:mace:shibboleth:2.0:metadata";
+
+    /** Logger. */
+    @Nonnull private static final Logger LOG = LoggerFactory.getLogger(ScriptTypeBeanParser.class);
+
+    /** Private c'tor. */
+    private ScriptTypeBeanParser() {
+        
+    }
+
+    /**
+     * Parse and return a builder for a bean adhering to the contract of ScriptedType.
+     * 
+     * @param type type of object to build
+     * @param element root of XML configuration
+     * 
+     * @return bean definition builder
+     */
+    @Nonnull public static BeanDefinitionBuilder parseScriptType(@Nonnull final Class type,
+            @Nonnull final Element element) {
+        
+        final BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(type);
+        
+        if (element.hasAttributeNS(null, "language")) {
+            final String scriptLanguage = StringSupport.trimOrNull(element.getAttributeNS(null, "language"));
+            builder.addConstructorArgValue(scriptLanguage);
+        }
+        final String customRef = StringSupport.trimOrNull(element.getAttributeNS(null, "customObjectRef"));
+        if (null != customRef) {
+            builder.addPropertyReference("customObject", customRef);
+        }
+        final Element scriptChild = ElementSupport.getFirstChildElement(element);
+        builder.addConstructorArgValue(ElementSupport.getElementContentAsString(scriptChild));
+        if (ElementSupport.isElementNamed(scriptChild, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+                "Script")) {
+            builder.setFactoryMethod("inlineScript");
+        } else if (ElementSupport.isElementNamed(scriptChild, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+                "ScriptFile")) {
+            builder.setFactoryMethod("resourceScript");
+        }
+        
+        return builder;
+    }
+    
+}
\ No newline at end of file
diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/impl/EntityAttributesFilterParser.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/impl/EntityAttributesFilterParser.java
index 570bb13..d99fe72 100644
--- a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/impl/EntityAttributesFilterParser.java
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/impl/EntityAttributesFilterParser.java
@@ -24,7 +24,8 @@ import javax.annotation.Nonnull;
 import javax.xml.namespace.QName;
 
 import net.shibboleth.idp.profile.spring.relyingparty.metadata.AbstractMetadataProviderParser;
-import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.idp.profile.spring.relyingparty.metadata.ScriptTypeBeanParser;
+import net.shibboleth.utilities.java.support.logic.ScriptedPredicate;
 import net.shibboleth.utilities.java.support.xml.ElementSupport;
 
 import org.opensaml.core.xml.XMLObject;
@@ -60,6 +61,7 @@ public class EntityAttributesFilterParser extends AbstractSingleBeanDefinitionPa
         return EntityAttributesFilter.class;
     }
 
+// Checkstyle: CyclomaticComplexity OFF
     /** {@inheritDoc} */
     @Override protected void doParse(final Element element, final ParserContext parserContext,
             final BeanDefinitionBuilder builder) {
@@ -75,6 +77,19 @@ public class EntityAttributesFilterParser extends AbstractSingleBeanDefinitionPa
         final ManagedMap<Object, ManagedList<Attribute>> ruleMap = new ManagedMap();
 
         Element child = ElementSupport.getFirstChildElement(element);
+        
+        // Check for Predicate at the top.
+        if (ElementSupport.isElementNamed(child, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+                "AttributeFilterRef")) {
+            builder.addPropertyReference("attributeFilter", ElementSupport.getElementContentAsString(child));
+            child = ElementSupport.getNextSiblingElement(child);
+        } else if (ElementSupport.isElementNamed(child, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+                "AttributeFilterScript")) {
+            builder.addPropertyValue("attributeFilter",
+                    ScriptTypeBeanParser.parseScriptType(ScriptedPredicate.class, child).getBeanDefinition());
+        }
+        
+        // Loop over remaining children.
         while (child != null) {
             if (ElementSupport.isElementNamed(child, Attribute.DEFAULT_ELEMENT_NAME)) {
                 try {
@@ -98,17 +113,19 @@ public class EntityAttributesFilterParser extends AbstractSingleBeanDefinitionPa
                 final ManagedList<Attribute> forRule = new ManagedList(accumulator.size());
                 forRule.addAll(accumulator);
                 ruleMap.put(new RuntimeBeanReference(ElementSupport.getElementContentAsString(child)), forRule);
+            } else if (ElementSupport.isElementNamed(child, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+                    "ConditionScript")) {
+                final ManagedList<Attribute> forRule = new ManagedList(accumulator.size());
+                forRule.addAll(accumulator);
+                ruleMap.put(ScriptTypeBeanParser.parseScriptType(ScriptedPredicate.class, child).getBeanDefinition(),
+                        forRule);
             }
             child = ElementSupport.getNextSiblingElement(child);
         }
 
         builder.addPropertyValue("rules", ruleMap);
-        
-        if (element.hasAttributeNS(null, "attributeFilterRef")) {
-            builder.addPropertyReference("attributeFilter",
-                    StringSupport.trimOrNull(element.getAttributeNS(null, "attributeFilterRef")));
-        }
     }
+// Checkstyle: CyclomaticComplexity ON
 
     /** {@inheritDoc} */
     @Override protected boolean shouldGenerateId() {
diff --git a/idp-profile-spring/src/test/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/AbstractMetadataParserTest.java b/idp-profile-spring/src/test/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/AbstractMetadataParserTest.java
index 5a76c34..0e5b094 100644
--- a/idp-profile-spring/src/test/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/AbstractMetadataParserTest.java
+++ b/idp-profile-spring/src/test/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/AbstractMetadataParserTest.java
@@ -44,6 +44,7 @@ import org.testng.annotations.BeforeSuite;
 
 import net.shibboleth.ext.spring.config.DurationToLongConverter;
 import net.shibboleth.ext.spring.config.StringToIPRangeConverter;
+import net.shibboleth.ext.spring.config.StringToResourceConverter;
 import net.shibboleth.ext.spring.context.FilesystemGenericApplicationContext;
 import net.shibboleth.ext.spring.util.SchemaTypeAwareXMLBeanDefinitionReader;
 import net.shibboleth.ext.spring.util.SpringSupport;
@@ -159,7 +160,10 @@ public class AbstractMetadataParserTest extends OpenSAMLInitBaseTestCase {
 
         final ConversionServiceFactoryBean service = new ConversionServiceFactoryBean();
         context.setDisplayName("ApplicationContext: " + contextName);
-        service.setConverters(new HashSet<>(Arrays.asList(new DurationToLongConverter(), new StringToIPRangeConverter())));
+        service.setConverters(new HashSet<>(Arrays.asList(
+                new DurationToLongConverter(),
+                new StringToIPRangeConverter(),
+                new StringToResourceConverter())));
         service.afterPropertiesSet();
 
         context.getBeanFactory().setConversionService(service.getObject());
diff --git a/idp-profile-spring/src/test/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/EntityAttributesFilterParserTest.java b/idp-profile-spring/src/test/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/EntityAttributesFilterParserTest.java
index 3b9790c..8fd35d8 100644
--- a/idp-profile-spring/src/test/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/EntityAttributesFilterParserTest.java
+++ b/idp-profile-spring/src/test/java/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/EntityAttributesFilterParserTest.java
@@ -38,9 +38,22 @@ public class EntityAttributesFilterParserTest extends AbstractMetadataParserTest
     
     @Test
     public void test() throws ResolverException, IOException {
+        doTest("filter/entityAttributes.xml", "filter/entityAttributesBeans.xml");
+    }
 
-        final MetadataResolver resolver = getBean(MetadataResolver.class,
-                "filter/entityAttributes.xml", "filter/entityAttributesBeans.xml");
+    @Test
+    public void testFilterScript() throws ResolverException, IOException {
+        doTest("filter/entityAttributesWithScript.xml");
+    }
+
+    @Test
+    public void testFilterScriptResource() throws ResolverException, IOException {
+        doTest("filter/entityAttributesWithScriptResource.xml");
+    }
+
+    private void doTest(final String... files) throws ResolverException, IOException {
+
+        final MetadataResolver resolver = getBean(MetadataResolver.class, files);
 
         final EntityAttributesFilter filter = (EntityAttributesFilter) resolver.getMetadataFilter();
         Assert.assertNotNull(filter);
@@ -73,5 +86,4 @@ public class EntityAttributesFilterParserTest extends AbstractMetadataParserTest
             }
         }
     }
-
 }
\ No newline at end of file
diff --git a/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml
index 3c2d282..fd30d2e 100644
--- a/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml
+++ b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml
@@ -12,7 +12,8 @@
 
 	id="entityAttributes" xsi:type="metadata:InlineMetadataProvider">
     
-	<metadata:MetadataFilter xsi:type="metadata:EntityAttributes" attributeFilterRef="predicate.AlwaysFalse">
+	<metadata:MetadataFilter xsi:type="metadata:EntityAttributes">
+        <metadata:AttributeFilterRef>predicate.AlwaysFalse</metadata:AttributeFilterRef>
         <saml:Attribute Name="foo">
             <saml:AttributeValue>fooValue</saml:AttributeValue>        
         </saml:Attribute>
diff --git a/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesAttributeFilterScript.js b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesAttributeFilterScript.js
new file mode 100644
index 0000000..2372bb1
--- /dev/null
+++ b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesAttributeFilterScript.js
@@ -0,0 +1,2 @@
+
+!input.getName().equals("http://macedir.org/entity-category");
diff --git a/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesConditionScript.js b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesConditionScript.js
new file mode 100644
index 0000000..9eefa45
--- /dev/null
+++ b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesConditionScript.js
@@ -0,0 +1,2 @@
+
+input.getEntityID().equals("https://sp.example.org/sp/shibboleth");
diff --git a/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesWithScript.xml
similarity index 87%
copy from idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml
copy to idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesWithScript.xml
index 3c2d282..b66fdc6 100644
--- a/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml
+++ b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesWithScript.xml
@@ -12,14 +12,19 @@
 
 	id="entityAttributes" xsi:type="metadata:InlineMetadataProvider">
     
-	<metadata:MetadataFilter xsi:type="metadata:EntityAttributes" attributeFilterRef="predicate.AlwaysFalse">
+	<metadata:MetadataFilter xsi:type="metadata:EntityAttributes">
+        <metadata:AttributeFilterScript>
+            <metadata:Script>!input.getName().equals("http://macedir.org/entity-category");</metadata:Script>
+        </metadata:AttributeFilterScript>
         <saml:Attribute Name="foo">
             <saml:AttributeValue>fooValue</saml:AttributeValue>        
         </saml:Attribute>
         <saml:Attribute Name="bar">
             <saml:AttributeValue>barValue</saml:AttributeValue>        
         </saml:Attribute>
-        <metadata:Entity>https://sp.example.org/sp/shibboleth</metadata:Entity>
+        <metadata:ConditionScript language="javascript">
+            <metadata:Script>input.getEntityID().equals("https://sp.example.org/sp/shibboleth");</metadata:Script>
+        </metadata:ConditionScript>
     </metadata:MetadataFilter>
 
     <EntitiesDescriptor Name="ukgroup">
diff --git a/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesWithScriptResource.xml
similarity index 84%
copy from idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml
copy to idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesWithScriptResource.xml
index 3c2d282..989a445 100644
--- a/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributes.xml
+++ b/idp-profile-spring/src/test/resources/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesWithScriptResource.xml
@@ -12,14 +12,19 @@
 
 	id="entityAttributes" xsi:type="metadata:InlineMetadataProvider">
     
-	<metadata:MetadataFilter xsi:type="metadata:EntityAttributes" attributeFilterRef="predicate.AlwaysFalse">
+	<metadata:MetadataFilter xsi:type="metadata:EntityAttributes">
+        <metadata:AttributeFilterScript>
+            <metadata:ScriptFile>classpath:/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesAttributeFilterScript.js</metadata:ScriptFile>
+        </metadata:AttributeFilterScript>
         <saml:Attribute Name="foo">
             <saml:AttributeValue>fooValue</saml:AttributeValue>        
         </saml:Attribute>
         <saml:Attribute Name="bar">
             <saml:AttributeValue>barValue</saml:AttributeValue>        
         </saml:Attribute>
-        <metadata:Entity>https://sp.example.org/sp/shibboleth</metadata:Entity>
+        <metadata:ConditionScript language="javascript">
+            <metadata:ScriptFile>classpath:/net/shibboleth/idp/profile/spring/relyingparty/metadata/filter/entityAttributesConditionScript.js</metadata:ScriptFile>
+        </metadata:ConditionScript>
     </metadata:MetadataFilter>
 
     <EntitiesDescriptor Name="ukgroup">
diff --git a/idp-schema/src/main/resources/schema/shibboleth-metadata.xsd b/idp-schema/src/main/resources/schema/shibboleth-metadata.xsd
index 2c1e57d..7b274ae 100644
--- a/idp-schema/src/main/resources/schema/shibboleth-metadata.xsd
+++ b/idp-schema/src/main/resources/schema/shibboleth-metadata.xsd
@@ -1129,39 +1129,59 @@
         </annotation>
         <complexContent>
             <extension base="shibmd:MetadataFilterType">
-                <choice minOccurs="0" maxOccurs="unbounded">
-                    <element ref="saml:Attribute">
-                        <annotation>
-                            <documentation>
-                                An Attribute to add to an EntityAttributes extension. 
-                            </documentation>
-                        </annotation>
-                    </element>
-                    <element name="Entity" type="string">
-                        <annotation>
-                            <documentation>
-                                An entityID to identify an EntityDescriptor to add all the preceding
-                                Attribute elements to. 
-                            </documentation>
-                        </annotation>
-                    </element>
-                    <element name="ConditionRef" type="string">
-                        <annotation>
-                            <documentation>
-                                The ID of a Spring bean to inject as a condition Predicate to identify one
-                                or more EntityDescriptors to add all the preceding Attribute elements to. 
-                            </documentation>
-                        </annotation>
-                    </element>
-                </choice>
-                <attribute name="attributeFilterRef" type="string">
-                    <annotation>
-                        <documentation>
-                            The ID of a Spring bean to inject as a condition Predicate to determine whether
-                            pre-existing EntityAttributes child Attributes should be retained.
-                        </documentation>
-                    </annotation>
-                </attribute>
+                <sequence>
+                    <choice minOccurs="0">
+                        <element name="AttributeFilterRef" type="string">
+                            <annotation>
+                                <documentation>
+                                    The ID of a Spring bean to inject as a condition Predicate to determine whether
+                                    pre-existing EntityAttributes child Attributes should be retained.
+                                </documentation>
+                            </annotation>
+                        </element>
+                        <element name="AttributeFilterScript" type="shibmd:ScriptType" minOccurs="0">
+                            <annotation>
+                                <documentation>
+                                    A script implementing Predicate<Attribute> to determine whether
+                                    pre-existing EntityAttributes child Attributes should be retained.
+                                </documentation>
+                            </annotation>
+                        </element>
+                    </choice>
+                    <choice minOccurs="0" maxOccurs="unbounded">
+                        <element ref="saml:Attribute">
+                            <annotation>
+                                <documentation>
+                                    An Attribute to add to an EntityAttributes extension. 
+                                </documentation>
+                            </annotation>
+                        </element>
+                        <element name="Entity" type="string">
+                            <annotation>
+                                <documentation>
+                                    An entityID to identify an EntityDescriptor to add all the preceding
+                                    Attribute elements to. 
+                                </documentation>
+                            </annotation>
+                        </element>
+                        <element name="ConditionRef" type="string">
+                            <annotation>
+                                <documentation>
+                                    The ID of a Spring bean to inject as a condition Predicate to identify one
+                                    or more EntityDescriptors to add all the preceding Attribute elements to. 
+                                </documentation>
+                            </annotation>
+                        </element>
+                        <element name="ConditionScript" type="shibmd:ScriptType">
+                            <annotation>
+                                <documentation>
+                                    A script implementing Predicate<EntityDescriptor> to identify one
+                                    or more EntityDescriptors to add all the preceding Attribute elements to. 
+                                </documentation>
+                            </annotation>
+                        </element>
+                    </choice>
+                </sequence>
             </extension>
         </complexContent>
     </complexType>
@@ -1338,4 +1358,42 @@
     </complexType>
     
     <complexType name="MetadataNodeProcessorType" abstract="true"/>
+    
+    <complexType name="ScriptType">
+        <annotation>
+            <documentation>
+                A type for elements that allow for scripts to be declared inline or via a resource.
+            </documentation>
+        </annotation>
+        <choice>
+            <element name="Script" type="string">
+                <annotation>
+                    <documentation>The script to evaluate to construct the attribute.</documentation>
+                </annotation>
+            </element>
+            <element name="ScriptFile" type="string">
+                <annotation>
+                    <documentation>
+                        Path of a local resource containing the script to evaluate to construct the attribute.
+                    </documentation>
+                </annotation>
+            </element>
+        </choice>
+        <attribute name="language" type="string">
+            <annotation>
+                <documentation>
+                    The JSR-233 name for the scripting language that will be used.
+                    By default "javascript" is assumed.
+                </documentation>
+            </annotation>
+        </attribute>
+        <attribute name="customObjectRef" type="string">
+            <annotation>
+                <documentation>
+                    The name of a bean defined somewhere else which will be injected into the script as an
+                    object called "custom". If not supplied, nothing is injected.
+                </documentation>
+            </annotation>
+        </attribute>
+    </complexType>
 </schema>

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list