You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by dv...@apache.org on 2011/10/06 23:07:29 UTC

svn commit: r1179853 - in /camel/trunk: camel-core/src/main/java/org/apache/camel/ camel-core/src/main/java/org/apache/camel/builder/ camel-core/src/main/java/org/apache/camel/impl/ camel-core/src/main/java/org/apache/camel/model/ components/camel-core...

Author: dvaleri
Date: Thu Oct  6 21:07:28 2011
New Revision: 1179853

URL: http://svn.apache.org/viewvc?rev=1179853&view=rev
Log:
[CAMEL-4520] [CAMEL-3775] Added support for custom prefix/suffix tokens and custom property name prefix and suffix strings to XML based configuration and fixed disabled OSGI itests for property placeholders.

Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/PropertyPlaceholderDelegateRegistry.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
    camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
    camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelPropertyPlaceholderDefinition.java
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/component/properties/SpringPropertiesComponent2Test.xml
    camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintExplicitPropertiesRouteTest.java
    camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintPropertiesRouteTest.java
    camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-16.xml

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java Thu Oct  6 21:07:28 2011
@@ -619,6 +619,22 @@ public interface CamelContext extends Su
      * @throws Exception is thrown if property placeholders was used and there was an error resolving them
      */
     String resolvePropertyPlaceholders(String text) throws Exception;
+    
+    /**
+     * Returns the configured property placeholder prefix token if and only if the context has
+     * property placeholder abilities, otherwise returns {@code null}.
+     * 
+     * @return the prefix token or {@code null}
+     */
+    String getPropertyPrefixToken();
+    
+    /**
+     * Returns the configured property placeholder suffix token if and only if the context has
+     * property placeholder abilities, otherwise returns {@code null}.
+     * 
+     * @return the suffix token or {@code null}
+     */
+    String getPropertySuffixToken();
 
     /**
      * Gets a readonly list with the names of the languages currently registered.
@@ -1037,5 +1053,4 @@ public interface CamelContext extends Su
      * @param useBreadcrumb <tt>true</tt> to enable breadcrumb, <tt>false</tt> to disable
      */
     void setUseBreadcrumb(Boolean useBreadcrumb);
-
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java Thu Oct  6 21:07:28 2011
@@ -1512,7 +1512,7 @@ public final class ExpressionBuilder {
                                 .mandatoryConvertTo(PropertiesComponent.class, component);
                         // enclose key with {{ }} to force parsing
                         String[] paths = locations.split(",");
-                        return pc.parseUri(PropertiesComponent.PREFIX_TOKEN + key + PropertiesComponent.SUFFIX_TOKEN, paths);
+                        return pc.parseUri(pc.getPrefixToken() + key + pc.getSuffixToken(), paths);
                     } else {
                         // the properties component is mandatory if no locations provided
                         Component component = exchange.getContext().hasComponent("properties");
@@ -1523,7 +1523,7 @@ public final class ExpressionBuilder {
                         PropertiesComponent pc = exchange.getContext().getTypeConverter()
                                 .mandatoryConvertTo(PropertiesComponent.class, component);
                         // enclose key with {{ }} to force parsing
-                        return pc.parseUri(PropertiesComponent.PREFIX_TOKEN + key + PropertiesComponent.SUFFIX_TOKEN);
+                        return pc.parseUri(pc.getPrefixToken() + key + pc.getSuffixToken());
                     }
                 } catch (Exception e) {
                     throw ObjectHelper.wrapRuntimeCamelException(e);

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java Thu Oct  6 21:07:28 2011
@@ -958,32 +958,53 @@ public class DefaultCamelContext extends
         // no language resolved
         return answer;
     }
+    
+    public String getPropertyPrefixToken() {
+        PropertiesComponent pc = getPropertiesComponent();
+        
+        if (pc != null) {
+            return pc.getPrefixToken();
+        } else {
+            return null;
+        }
+    }
+    
+    public String getPropertySuffixToken() {
+        PropertiesComponent pc = getPropertiesComponent();
+        
+        if (pc != null) {
+            return pc.getSuffixToken();
+        } else {
+            return null;
+        }
+    }
 
     public String resolvePropertyPlaceholders(String text) throws Exception {
-        // do not parse uris that are designated for the properties component as it will handle that itself
-        if (text != null && !text.startsWith("properties:") && text.contains(PropertiesComponent.PREFIX_TOKEN)) {
-            // the uri contains property placeholders so lookup mandatory properties component and let it parse it
-            Component component = hasComponent("properties");
-            if (component == null) {
-                // then fallback to lookup the component
-                component = getRegistry().lookup("properties", Component.class);
-            }
-            if (component == null) {
+        // While it is more efficient to only do the lookup if we are sure we need the component,
+        // with custom tokens, we cannot know if the URI contains a property or not without having
+        // the component.  We also lose fail-fast behavior for the missing component with this change.
+        PropertiesComponent pc = getPropertiesComponent();
+        
+        // Do not parse uris that are designated for the properties component as it will handle that itself
+        if (text != null && !text.startsWith("properties:")) {
+            // No component, assume default tokens.
+            if (pc == null && text.contains(PropertiesComponent.DEFAULT_PREFIX_TOKEN)) {
                 throw new IllegalArgumentException("PropertiesComponent with name properties must be defined"
                         + " in CamelContext to support property placeholders.");
+                
+            // Component available, use actual tokens
+            } else if (pc != null && text.contains(pc.getPrefixToken())) {
+                // the parser will throw exception if property key was not found
+                String answer = pc.parseUri(text);
+                log.debug("Resolved text: {} -> {}", text, answer);
+                return answer; 
             }
-            // force component to be created and registered as a component
-            PropertiesComponent pc = getComponent("properties", PropertiesComponent.class);
-            // the parser will throw exception if property key was not found
-            String answer = pc.parseUri(text);
-            log.debug("Resolved text: {} -> {}", text, answer);
-            return answer;
         }
 
         // return original text as is
         return text;
     }
-
+    
     // Properties
     // -----------------------------------------------------------------------
 
@@ -2066,6 +2087,27 @@ public class DefaultCamelContext extends
     protected boolean shouldStartRoutes() {
         return isStarted() && !isStarting();
     }
+    
+    /**
+     * Looks up the properties component if one may be resolved or has already been created.
+     * Returns {@code null} if one was not created or is not in the registry.
+     */
+    protected PropertiesComponent getPropertiesComponent() {
+        Component component = hasComponent("properties");
+        if (component == null) {
+            // then fallback to lookup the component
+            component = getRegistry().lookup("properties", Component.class);
+        }
+        
+        PropertiesComponent pc = null;
+        // Ensure that we don't create one if one is not really available.
+        if (component != null) {
+            // force component to be created and registered as a component
+            pc = getComponent("properties", PropertiesComponent.class);
+        }
+        
+        return pc;
+    }
 
     public void setDataFormats(Map<String, DataFormatDefinition> dataFormats) {
         this.dataFormats = dataFormats;

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/PropertyPlaceholderDelegateRegistry.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/PropertyPlaceholderDelegateRegistry.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/PropertyPlaceholderDelegateRegistry.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/PropertyPlaceholderDelegateRegistry.java Thu Oct  6 21:07:28 2011
@@ -41,7 +41,11 @@ public class PropertyPlaceholderDelegate
 
     public Object lookup(String name) {
         try {
-            name = context.resolvePropertyPlaceholders(name);
+            // Must avoid attempting placeholder resolution when looking up
+            // the properties component or else we end up in an infinite loop.
+            if (!name.equals("properties")) {
+                name = context.resolvePropertyPlaceholders(name);
+            }
             return delegate.lookup(name);
         } catch (Exception e) {
             throw ObjectHelper.wrapRuntimeCamelException(e);
@@ -50,7 +54,11 @@ public class PropertyPlaceholderDelegate
 
     public <T> T lookup(String name, Class<T> type) {
         try {
-            name = context.resolvePropertyPlaceholders(name);
+            // Must avoid attempting placeholder resolution when looking up
+            // the properties component or else we end up in an infinite loop.
+            if (!name.equals("properties")) {
+                name = context.resolvePropertyPlaceholders(name);
+            }
             return delegate.lookup(name, type);
         } catch (Exception e) {
             throw ObjectHelper.wrapRuntimeCamelException(e);

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java Thu Oct  6 21:07:28 2011
@@ -471,11 +471,17 @@ public abstract class ProcessorDefinitio
                     if (value != null && value instanceof String) {
                         // value must be enclosed with placeholder tokens
                         String s = (String) value;
-                        if (!s.startsWith(PropertiesComponent.PREFIX_TOKEN)) {
-                            s = PropertiesComponent.PREFIX_TOKEN + s;
+                        String prefixToken = routeContext.getCamelContext().getPropertyPrefixToken();
+                        String suffixToken = routeContext.getCamelContext().getPropertySuffixToken();
+                        if (prefixToken == null) {
+                            throw new IllegalArgumentException("Property with name [" + local + "] uses property placeholders; however, no properties component is configured.");
                         }
-                        if (!s.endsWith(PropertiesComponent.SUFFIX_TOKEN)) {
-                            s = s + PropertiesComponent.SUFFIX_TOKEN;
+                        
+                        if (!s.startsWith(prefixToken)) {
+                            s = prefixToken + s;
+                        }
+                        if (!s.endsWith(suffixToken)) {
+                            s = s + suffixToken;
                         }
                         value = s;
                     }

Modified: camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java (original)
+++ camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java Thu Oct  6 21:07:28 2011
@@ -411,6 +411,16 @@ public abstract class AbstractCamelConte
                                                                              PropertiesParser.class);
                 pc.setPropertiesParser(parser);
             }
+            
+            pc.setPropertyPrefix(def.getPropertyPrefix());
+            pc.setPropertySuffix(def.getPropertySuffix());
+            
+            if (def.isFallbackToUnaugmentedProperty() != null) {
+                pc.setFallbackToUnaugmentedProperty(def.isFallbackToUnaugmentedProperty());
+            }
+            
+            pc.setPrefixToken(def.getPrefixToken());
+            pc.setSuffixToken(def.getSuffixToken());
 
             // register the properties component
             getContext().addComponent("properties", pc);

Modified: camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelPropertyPlaceholderDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelPropertyPlaceholderDefinition.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelPropertyPlaceholderDefinition.java (original)
+++ camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelPropertyPlaceholderDefinition.java Thu Oct  6 21:07:28 2011
@@ -40,6 +40,21 @@ public class CamelPropertyPlaceholderDef
 
     @XmlAttribute
     private String propertiesParserRef;
+    
+    @XmlAttribute
+    private String propertyPrefix;
+    
+    @XmlAttribute
+    private String propertySuffix;
+    
+    @XmlAttribute
+    private Boolean fallbackToUnaugmentedProperty;
+    
+    @XmlAttribute
+    private String prefixToken;
+    
+    @XmlAttribute
+    private String suffixToken;
 
     public String getLocation() {
         return location;
@@ -64,4 +79,44 @@ public class CamelPropertyPlaceholderDef
     public void setPropertiesParserRef(String propertiesParserRef) {
         this.propertiesParserRef = propertiesParserRef;
     }
+
+    public String getPropertyPrefix() {
+        return propertyPrefix;
+    }
+
+    public void setPropertyPrefix(String propertyPrefix) {
+        this.propertyPrefix = propertyPrefix;
+    }
+
+    public String getPropertySuffix() {
+        return propertySuffix;
+    }
+
+    public void setPropertySuffix(String propertySuffix) {
+        this.propertySuffix = propertySuffix;
+    }
+
+    public Boolean isFallbackToUnaugmentedProperty() {
+        return fallbackToUnaugmentedProperty;
+    }
+
+    public void setFallbackToUnaugmentedProperty(Boolean fallbackToUnaugmentedProperty) {
+        this.fallbackToUnaugmentedProperty = fallbackToUnaugmentedProperty;
+    }
+
+    public String getPrefixToken() {
+        return prefixToken;
+    }
+
+    public void setPrefixToken(String prefixToken) {
+        this.prefixToken = prefixToken;
+    }
+
+    public String getSuffixToken() {
+        return suffixToken;
+    }
+
+    public void setSuffixToken(String suffixToken) {
+        this.suffixToken = suffixToken;
+    }
 }

Modified: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/component/properties/SpringPropertiesComponent2Test.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/component/properties/SpringPropertiesComponent2Test.xml?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/component/properties/SpringPropertiesComponent2Test.xml (original)
+++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/component/properties/SpringPropertiesComponent2Test.xml Thu Oct  6 21:07:28 2011
@@ -26,26 +26,29 @@
 
         <propertyPlaceholder id="properties"
                              location="classpath:org/apache/camel/component/properties/cheese.properties"
+                             prefixToken="[["
+                             suffixToken="]]"
+                             propertyPrefix="cool."
                              xmlns="http://camel.apache.org/schema/spring"/>
 
         <route>
             <from uri="direct:start"/>
-            <to uri="properties:{{cool.end}}"/>
+            <to uri="properties:[[end]]"/>
         </route>
 
         <route>
             <from uri="direct:bar"/>
-            <to uri="properties:mock:{{cool.bar}}"/>
+            <to uri="properties:mock:[[bar]]"/>
         </route>
 
         <route>
             <from uri="direct:start2"/>
-            <to uri="{{cool.end}}"/>
+            <to uri="[[end]]"/>
         </route>
 
         <route>
             <from uri="direct:bar2"/>
-            <to uri="mock:{{cool.bar}}"/>
+            <to uri="mock:[[bar]]"/>
         </route>
     </camelContext>
 

Modified: camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintExplicitPropertiesRouteTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintExplicitPropertiesRouteTest.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintExplicitPropertiesRouteTest.java (original)
+++ camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintExplicitPropertiesRouteTest.java Thu Oct  6 21:07:28 2011
@@ -34,7 +34,6 @@ import static org.ops4j.pax.swissbox.tin
 /**
  *
  */
-@Ignore("Got NPE error when the CmPropertyPlaceholder init is called")
 @RunWith(JUnit4TestRunner.class)
 public class BlueprintExplicitPropertiesRouteTest extends OSGiBlueprintTestSupport {
 
@@ -74,6 +73,7 @@ public class BlueprintExplicitProperties
             bundle(newBundle()
                 .add("OSGI-INF/blueprint/test.xml", BlueprintExplicitPropertiesRouteTest.class.getResource("blueprint-16.xml"))
                 .set(Constants.BUNDLE_SYMBOLICNAME, BlueprintExplicitPropertiesRouteTest.class.getName())
+                .set(Constants.BUNDLE_VERSION, "1.0.0")
                 .build()).noStart(),
                 
             // using the features to install the camel components

Modified: camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintPropertiesRouteTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintPropertiesRouteTest.java?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintPropertiesRouteTest.java (original)
+++ camel/trunk/tests/camel-itest-osgi/src/test/java/org/apache/camel/itest/osgi/blueprint/BlueprintPropertiesRouteTest.java Thu Oct  6 21:07:28 2011
@@ -34,7 +34,6 @@ import static org.ops4j.pax.swissbox.tin
 /**
  *
  */
-@Ignore("Got NPE error when the CmPropertyPlaceholder init is called")
 @RunWith(JUnit4TestRunner.class)
 public class BlueprintPropertiesRouteTest extends OSGiBlueprintTestSupport {
 
@@ -74,6 +73,7 @@ public class BlueprintPropertiesRouteTes
                 bundle(newBundle()
                         .add("OSGI-INF/blueprint/test.xml", BlueprintPropertiesRouteTest.class.getResource("blueprint-17.xml"))
                         .set(Constants.BUNDLE_SYMBOLICNAME, BlueprintPropertiesRouteTest.class.getName())
+                        .set(Constants.BUNDLE_VERSION, "1.0.0")
                         .build()).noStart(),
 
                 // using the features to install the camel components

Modified: camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-16.xml
URL: http://svn.apache.org/viewvc/camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-16.xml?rev=1179853&r1=1179852&r2=1179853&view=diff
==============================================================================
--- camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-16.xml (original)
+++ camel/trunk/tests/camel-itest-osgi/src/test/resources/org/apache/camel/itest/osgi/blueprint/blueprint-16.xml Thu Oct  6 21:07:28 2011
@@ -26,20 +26,22 @@
     <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint">
         <!-- list some properties for this test -->
         <cm:default-properties>
-            <cm:property name="result" value="mock:result"/>
+            <cm:property name="prefix.result" value="mock:result"/>
         </cm:default-properties>
     </cm:property-placeholder>
 
     <camelContext xmlns="http://camel.apache.org/schema/blueprint">
 
         <!-- using Camel properties component and refer to the blueprint property placeholder by its id -->
-        <propertyPlaceholder id="properties" location="blueprint:myblueprint.placeholder"/>
+        <propertyPlaceholder id="properties" location="blueprint:myblueprint.placeholder"
+                             prefixToken="[[" suffixToken="]]"
+                             propertyPrefix="prefix."/>
 
         <!-- in the route we can use {{ }} placeholders which will lookup in blueprint -->
         <route>
             <from uri="direct:start"/>
             <to uri="mock:foo"/>
-            <to uri="{{result}}"/>
+            <to uri="[[result]]"/>
         </route>
 
     </camelContext>