Author: rwonly
Date: Thu Sep 1 06:54:04 2011
New Revision: 1163921
URL: http://svn.apache.org/viewvc?rev=1163921&view=rev
Log:
AARIES-727 support syntax : ${a+b} in blueprint-ext (porting rev
1162308-1163899 from 0.3 branch)
Added:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/JexlExpressionParser.java
(with props)
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ext/PropertyPlaceholderTest.java
(with props)
Modified:
aries/trunk/blueprint/ (props changed)
aries/trunk/blueprint/blueprint-bundle/pom.xml
aries/trunk/blueprint/blueprint-core/pom.xml
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/
(props changed)
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/PropertyPlaceholder.java
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/
(props changed)
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholderTest.java
Propchange: aries/trunk/blueprint/
------------------------------------------------------------------------------
svn:mergeinfo = /aries/branches/0.3-RCx/blueprint:1162308-1163911
Modified: aries/trunk/blueprint/blueprint-bundle/pom.xml
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-bundle/pom.xml?rev=1163921&r1=1163920&r2=1163921&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-bundle/pom.xml (original)
+++ aries/trunk/blueprint/blueprint-bundle/pom.xml Thu Sep 1 06:54:04 2011
@@ -58,6 +58,7 @@
org.apache.aries.blueprint.annotation.service;resolution:=optional,
org.apache.aries.quiesce.manager;version="[0.2,1.0)";resolution:=optional,
org.apache.aries.quiesce.participant;version="[0.2,1.0)";resolution:=optional,
+ org.apache.commons.jexl2;resolution:=optional,
*
</aries.osgi.import>
<!-- Export package versions are maintained in packageinfo files -->
Modified: aries/trunk/blueprint/blueprint-core/pom.xml
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/pom.xml?rev=1163921&r1=1163920&r2=1163921&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/pom.xml (original)
+++ aries/trunk/blueprint/blueprint-core/pom.xml Thu Sep 1 06:54:04 2011
@@ -119,6 +119,11 @@
<version>3.2</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-jexl</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.aries.quiesce</groupId>
<artifactId>org.apache.aries.quiesce.api</artifactId>
<scope>provided</scope>
Propchange: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/
('svn:mergeinfo' removed)
Modified:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java?rev=1163921&r1=1163920&r2=1163921&view=diff
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java
(original)
+++
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java
Thu Sep 1 06:54:04 2011
@@ -52,6 +52,8 @@ import org.osgi.service.blueprint.reflec
import org.osgi.service.blueprint.reflect.ServiceMetadata;
import org.osgi.service.blueprint.reflect.Target;
import org.osgi.service.blueprint.reflect.ValueMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Abstract class for property placeholders.
@@ -60,6 +62,8 @@ import org.osgi.service.blueprint.reflec
*/
public abstract class AbstractPropertyPlaceholder implements
ComponentDefinitionRegistryProcessor {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(AbstractPropertyPlaceholder.class);
+
private String placeholderPrefix = "${";
private String placeholderSuffix = "}";
private Pattern pattern;
@@ -193,11 +197,15 @@ public abstract class AbstractPropertyPl
return new LateBindingValueMetadata(metadata);
}
+ protected String retrieveValue(String expression) {
+ return getProperty(expression);
+ }
+
protected String processString(String str) {
// TODO: we need to handle escapes on the prefix / suffix
Matcher matcher = getPattern().matcher(str);
while (matcher.find()) {
- String rep = getProperty(matcher.group(1));
+ String rep = retrieveValue(matcher.group(1));
if (rep != null) {
str = str.replace(matcher.group(0), rep);
matcher.reset(str);
@@ -229,8 +237,12 @@ public abstract class AbstractPropertyPl
public String getStringValue() {
if (!retrieved) {
+ String v = metadata.getStringValue();
+ LOGGER.debug("Before process: {}", v);
+ retrievedValue = processString(v);
+ LOGGER.debug("After process: {}", retrievedValue);
+
retrieved = true;
- retrievedValue = processString(metadata.getStringValue());
}
return retrievedValue;
}
Added:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/JexlExpressionParser.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/JexlExpressionParser.java?rev=1163921&view=auto
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/JexlExpressionParser.java
(added)
+++
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/JexlExpressionParser.java
Thu Sep 1 06:54:04 2011
@@ -0,0 +1,60 @@
+/*
+ * 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.aries.blueprint.ext;
+
+import java.util.Map;
+
+import org.apache.commons.jexl2.JexlContext;
+import org.apache.commons.jexl2.JexlEngine;
+import org.apache.commons.jexl2.MapContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Rev: 907189 $ $Date: 2010-02-06 16:01:43 +0800 (Sat, 06 Feb 2010)
$
+ */
+public class JexlExpressionParser {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(JexlExpressionParser.class);
+
+ protected final JexlContext context;
+ private final JexlEngine engine;
+
+ public JexlExpressionParser(final Map<String, Object> vars) {
+ if (vars == null) {
+ throw new IllegalArgumentException("vars: " + vars);
+ }
+ engine = new JexlEngine();
+ context = new MapContext(vars);
+
+ LOGGER.trace("Using variables: {}", vars);
+ }
+
+ public Object evaluate(final String expression) throws Exception {
+ if (expression == null) {
+ throw new IllegalArgumentException("expression: " + expression);
+ }
+
+ LOGGER.trace("Evaluating expression: {}", expression);
+ return engine.createExpression(expression).evaluate(context);
+
+ }
+
+}
Propchange:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/JexlExpressionParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/PropertyPlaceholder.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/PropertyPlaceholder.java?rev=1163921&r1=1163920&r2=1163921&view=diff
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/PropertyPlaceholder.java
(original)
+++
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/PropertyPlaceholder.java
Thu Sep 1 06:54:04 2011
@@ -21,9 +21,11 @@ package org.apache.aries.blueprint.ext;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,7 +50,8 @@ public class PropertyPlaceholder extends
private List<URL> locations;
private boolean ignoreMissingLocations;
private SystemProperties systemProperties = SystemProperties.fallback;
-
+ private transient JexlExpressionParser jexlParser;
+
public Map getDefaultProperties() {
return defaultProperties;
}
@@ -139,4 +142,101 @@ public class PropertyPlaceholder extends
return v != null ? v.toString() : null;
}
+ @Override
+ protected String retrieveValue(String expression) {
+ LOGGER.debug("Retrieving Value from expression: {}", expression);
+ String result = super.retrieveValue(expression);
+
+ if (result == null){
+ try {
+ Class.forName("org.apache.commons.jexl2.JexlEngine");
+ JexlExpressionParser parser = getJexlParser();
+ try {
+ Object obj = parser.evaluate(expression);
+ if (obj!=null) {
+ result = obj.toString();
+ }
+ } catch (Exception e) {
+ LOGGER.info("Could not evaluate expression: {}",
expression);
+ LOGGER.info("Exception:", e);
+ }
+ } catch (ClassNotFoundException e) {
+ LOGGER.info("Could not evaluate expression: {}", expression);
+ LOGGER.info("Exception:", e);
+ }
+ }
+ return result;
+ }
+
+ private synchronized JexlExpressionParser getJexlParser() {
+ if (jexlParser == null) {
+ jexlParser = new JexlExpressionParser(toMap());
+ }
+ return jexlParser;
+ }
+
+ private Map<String, Object> toMap() {
+ return new Map<String, Object>() {
+ @Override
+ public boolean containsKey(Object o) {
+ return getProperty((String) o) != null;
+ }
+
+ @Override
+ public Object get(Object o) {
+ return getProperty((String) o);
+ }
+
+ // following are not important
+ @Override
+ public Object put(String s, Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int size() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean containsValue(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object remove(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void putAll(Map<? extends String, ? extends Object> map) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<String> keySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection<Object> values() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<Entry<String, Object>> entrySet() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
}
Propchange: aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/
('svn:mergeinfo' removed)
Added:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ext/PropertyPlaceholderTest.java
URL:
http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ext/PropertyPlaceholderTest.java?rev=1163921&view=auto
==============================================================================
---
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ext/PropertyPlaceholderTest.java
(added)
+++
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ext/PropertyPlaceholderTest.java
Thu Sep 1 06:54:04 2011
@@ -0,0 +1,93 @@
+/**
+ * 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.aries.blueprint.ext;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.service.blueprint.reflect.ValueMetadata;
+
+public class PropertyPlaceholderTest extends PropertyPlaceholder {
+ private final Map<String,String> values = new HashMap<String,String>();
+ private LateBindingValueMetadata sut;
+
+ @Before
+ public void setup() {
+ values.clear();
+ bind("prop1","hello");
+ bind("prop2","world");
+ bind("prop3","10");
+ bind("prop4","20");
+ }
+
+ @Test
+ public void singleProp() {
+ sut = makeProperty("${prop1}");
+ assertEquals("hello", sut.getStringValue());
+ }
+
+ @Test
+ public void multipleProps() {
+ sut = makeProperty("say ${prop1} ${prop2}");
+ assertEquals("say hello world", sut.getStringValue());
+ }
+
+ @Test
+ public void evaluateStringProps() {
+ sut = makeProperty("${prop1+prop2}");
+ assertEquals("helloworld", sut.getStringValue());
+ }
+
+ @Test
+ public void evaluateIntProps() {
+ sut = makeProperty("${prop3+prop4}");
+ assertEquals("30", sut.getStringValue());
+ }
+
+
+
+ /*
+ * Test helper methods
+ */
+
+ // Override to simulate actual property retrieval
+ protected String getProperty(String prop) {
+ return values.get(prop);
+ }
+
+ private void bind(String prop, String val) {
+ values.put(prop, val);
+ }
+
+ private LateBindingValueMetadata makeProperty(final String prop) {
+ return new LateBindingValueMetadata(new ValueMetadata() {
+ public String getType() {
+ return null;
+ }
+
+ public String getStringValue() {
+ return prop;
+ }
+ });
+ }
+}
Propchange:
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/ext/PropertyPlaceholderTest.java
------------------------------------------------------------------------------
svn:eol-style = native