You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by at...@apache.org on 2008/03/31 01:47:11 UTC
svn commit: r642842 -
/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/
Author: ate
Date: Sun Mar 30 16:47:07 2008
New Revision: 642842
URL: http://svn.apache.org/viewvc?rev=642842&view=rev
Log:
Restarting support for dynamic Spring assembly filtering based on configurable categories and bean meta data.
The previous solution using a Spring BeanFactoryPostProcessor didn't work out for all required use-cases.
This solution is more directly going to *prevent* registering BeanDefinitions.
Concrete Implementation and usage of these will follow later.
Added:
portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ApplicationContextBootPropertiesConfigurer.java (with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringClassPathXmlApplicationContext.java (with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringFileSystemXmlApplicationContext.java (with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringListableBeanFactory.java (with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringXmlWebApplicationContext.java (with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/JetspeedBeanDefinitionFilter.java (with props)
Added: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ApplicationContextBootPropertiesConfigurer.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ApplicationContextBootPropertiesConfigurer.java?rev=642842&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ApplicationContextBootPropertiesConfigurer.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ApplicationContextBootPropertiesConfigurer.java Sun Mar 30 16:47:07 2008
@@ -0,0 +1,52 @@
+/*
+ * 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.jetspeed.components;
+
+import java.util.Properties;
+
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/**
+ * Configures and adds a Spring PropertyPlaceholderConfigurer to an ConfigurableApplicationContext
+ * for replacing specific property placeholders at initialization time.
+ * <p>
+ * The PropertyPlaceholderConfigurer will be setup to ignore unresolved property placeholders
+ * and to <emp>never</emp> fallback to System properties if a property is unresolved.
+ * </p>
+ * <p>
+ * The PropertyPlaceholderConfigurer is then added to the provided ConfigurableApplicationContext
+ * using {@link ConfigurableApplicationContext#addBeanFactoryPostProcessor}.
+ * <p/>
+ * <p>
+ * This should be done before the context is refreshed for the first time.
+ * </p>
+ *
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class ApplicationContextBootPropertiesConfigurer
+{
+ public static void init(ConfigurableApplicationContext context, Properties bootProperties)
+ {
+ PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_NEVER);
+ ppc.setProperties(bootProperties);
+ context.addBeanFactoryPostProcessor(ppc);
+ }
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ApplicationContextBootPropertiesConfigurer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ApplicationContextBootPropertiesConfigurer.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/ApplicationContextBootPropertiesConfigurer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringClassPathXmlApplicationContext.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringClassPathXmlApplicationContext.java?rev=642842&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringClassPathXmlApplicationContext.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringClassPathXmlApplicationContext.java Sun Mar 30 16:47:07 2008
@@ -0,0 +1,58 @@
+/*
+ * 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.jetspeed.components;
+
+import java.util.Properties;
+
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class FilteringClassPathXmlApplicationContext extends ClassPathXmlApplicationContext
+{
+ private JetspeedBeanDefinitionFilter filter;
+
+ public FilteringClassPathXmlApplicationContext(JetspeedBeanDefinitionFilter filter, String[] configLocations, Properties initProperties)
+ {
+ this(filter, configLocations, initProperties, null);
+ }
+
+ public FilteringClassPathXmlApplicationContext(JetspeedBeanDefinitionFilter filter, String[] configLocations, Properties initProperties, ApplicationContext parent)
+ {
+ super(parent);
+ if (initProperties != null)
+ {
+ PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_FALLBACK);
+ ppc.setProperties(initProperties);
+ this.addBeanFactoryPostProcessor(ppc);
+ }
+ this.setConfigLocations(configLocations);
+ this.filter = filter;
+ }
+
+ protected DefaultListableBeanFactory createBeanFactory()
+ {
+ return new FilteringListableBeanFactory(filter, getInternalParentBeanFactory());
+ }
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringClassPathXmlApplicationContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringClassPathXmlApplicationContext.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringClassPathXmlApplicationContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringFileSystemXmlApplicationContext.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringFileSystemXmlApplicationContext.java?rev=642842&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringFileSystemXmlApplicationContext.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringFileSystemXmlApplicationContext.java Sun Mar 30 16:47:07 2008
@@ -0,0 +1,62 @@
+/*
+ * 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.jetspeed.components;
+
+import java.util.Properties;
+
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.FileSystemXmlApplicationContext;
+
+/**
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class FilteringFileSystemXmlApplicationContext extends FileSystemXmlApplicationContext
+{
+ private JetspeedBeanDefinitionFilter filter;
+
+ public FilteringFileSystemXmlApplicationContext(JetspeedBeanDefinitionFilter filter, String[] configLocations, Properties initProperties)
+ {
+ this(filter, configLocations, initProperties, null);
+ }
+
+ public FilteringFileSystemXmlApplicationContext(JetspeedBeanDefinitionFilter filter, String[] configLocations, Properties initProperties, ApplicationContext parent)
+ {
+ super();
+ if (parent != null)
+ {
+ this.setParent(parent);
+ }
+ if (initProperties != null)
+ {
+ PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_FALLBACK);
+ ppc.setProperties(initProperties);
+ this.addBeanFactoryPostProcessor(ppc);
+ }
+ this.setConfigLocations(configLocations);
+ this.filter = filter;
+ }
+
+ protected DefaultListableBeanFactory createBeanFactory()
+ {
+ return new FilteringListableBeanFactory(filter, getInternalParentBeanFactory());
+ }
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringFileSystemXmlApplicationContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringFileSystemXmlApplicationContext.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringFileSystemXmlApplicationContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringListableBeanFactory.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringListableBeanFactory.java?rev=642842&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringListableBeanFactory.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringListableBeanFactory.java Sun Mar 30 16:47:07 2008
@@ -0,0 +1,62 @@
+/*
+ * 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.jetspeed.components;
+
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+
+/**
+ * Extension of the default/standard Spring BeanFactory (as used by Jetspeed) to allow
+ * conditional filtering of BeanDefinition with the (optionally) provided JetspeedBeanDefinitionFilter.
+ *
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class FilteringListableBeanFactory extends DefaultListableBeanFactory
+{
+ private JetspeedBeanDefinitionFilter filter;
+
+ public FilteringListableBeanFactory(JetspeedBeanDefinitionFilter filter, BeanFactory parentBeanFactory)
+ {
+ super(parentBeanFactory);
+ this.filter = filter;
+ if (filter != null)
+ {
+ this.filter.init();
+ }
+ }
+
+ /**
+ * Override of the registerBeanDefinition method to optionally filter out a BeanDefinition and
+ * if requested dynamically register an bean alias
+ */
+ public void registerBeanDefinition(String beanName, BeanDefinition bd)
+ throws BeanDefinitionStoreException
+ {
+ boolean match = filter != null && filter.match(bd);
+ if (filter == null || match)
+ {
+ super.registerBeanDefinition(beanName, bd);
+ if (filter != null)
+ {
+ filter.registerDynamicAlias(this, beanName, bd);
+ }
+ }
+ }
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringListableBeanFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringListableBeanFactory.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringListableBeanFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringXmlWebApplicationContext.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringXmlWebApplicationContext.java?rev=642842&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringXmlWebApplicationContext.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringXmlWebApplicationContext.java Sun Mar 30 16:47:07 2008
@@ -0,0 +1,65 @@
+/*
+ * 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.jetspeed.components;
+
+import java.util.Properties;
+
+import javax.servlet.ServletContext;
+
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.context.support.XmlWebApplicationContext;
+
+/**
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class FilteringXmlWebApplicationContext extends XmlWebApplicationContext
+{
+ private JetspeedBeanDefinitionFilter filter;
+
+ public FilteringXmlWebApplicationContext(JetspeedBeanDefinitionFilter filter, String[] configLocations, Properties initProperties, ServletContext servletContext)
+ {
+ this(filter, configLocations, initProperties, servletContext, null);
+ }
+
+ public FilteringXmlWebApplicationContext(JetspeedBeanDefinitionFilter filter, String[] configLocations, Properties initProperties, ServletContext servletContext, ApplicationContext parent)
+ {
+ super();
+ if (parent != null)
+ {
+ this.setParent(parent);
+ }
+ if (initProperties != null)
+ {
+ PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
+ ppc.setIgnoreUnresolvablePlaceholders(true);
+ ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_FALLBACK);
+ ppc.setProperties(initProperties);
+ addBeanFactoryPostProcessor(ppc);
+ }
+ setConfigLocations(configLocations);
+ setServletContext(servletContext);
+ this.filter = filter;
+ }
+
+ protected DefaultListableBeanFactory createBeanFactory()
+ {
+ return new FilteringListableBeanFactory(filter, getInternalParentBeanFactory());
+ }
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringXmlWebApplicationContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringXmlWebApplicationContext.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/FilteringXmlWebApplicationContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/JetspeedBeanDefinitionFilter.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/JetspeedBeanDefinitionFilter.java?rev=642842&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/JetspeedBeanDefinitionFilter.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/JetspeedBeanDefinitionFilter.java Sun Mar 30 16:47:07 2008
@@ -0,0 +1,377 @@
+/*
+ * 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.jetspeed.components;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.BeanDefinitionValidationException;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PropertiesLoaderSupport;
+
+/**
+ * The JetspeedBeanDefinitionFilter makes it possible to dynamically filter out a BeanDefinition
+ * before it is registered in a Spring BeanFactory based on category meta data in the Spring configuration.
+ * <p>
+ * Categories definitions are loaded from one or more properties files and are simply sets of names to
+ * evaluate bean definitions against. A categories set is a comma separated list of names.
+ * Multiple sets of categories can be defined in the provided properties files, and also reference (include)
+ * each other using standard ${property} syntax.
+ * </p>
+ * <p>
+ * A specific property containing the categories to be used for filtering is defined through
+ * method {@link #setCategoriesKey}, or as <code>JetspeedBeanDefinitionFilter.categoriesKey</code>
+ * property in one of the loaded property files, or as System (-D) parameter.
+ * A System parameter is checked first, then the loaded properties and only as last resort the bean property itself.
+ * </p>
+ * <p>
+ * The categories set to be used can also be set directly through the {@link #categories} method.
+ * </p>
+ * <p>
+ * Beans which needs to be matched against active categories must define a:<br/>
+ * <pre><meta key="j2:cat" value="<categories>"/></pre> meta value within the bean definition.
+ * The bean categories value may contain multiple comma separated values.
+ * </p>
+ * <p>
+ * Unmatched beans (having a "j2:cat" meta value for which none were active) will not be registered in the
+ * Spring beanFactory (see: {@link FilteringListableBeanFactory}. By not defining an id or name attribute,
+ * or a unique one not referenced by other beans with different (or no) set of categories, different versions
+ * of a similar bean can be defined within a single Spring configuration file.
+ * </p>
+ * <p>
+ * Additionally an alias can be defined as bean meta value, allowing multiple beans to
+ * be defined using the same alias:<br/>
+ * <pre><meta key="j2:alias" value="<alias>"/></pre>
+ * Only a matched bean its alias will be registered and thereby able to be referenced by other beans
+ * (on this dynamically created alias).
+ * For this type of "enabling" only one of many possible beans definitions, these beans should
+ * not define an id or name attribute directly, or only an unique one which is not referenced or
+ * only referenced by other beans which have a "matching" j2:cat meta value.
+ * </p>
+ * <p>
+ * Optionally, all beans without a "j2:cat" meta value can be set to lazy initialization
+ * too, through method {@link #setDefaultLazyInit} (default value: null). This property can also
+ * be defined directly as <code>CategoryFilteringPostProcessor.defaultLazyInit</code> property in one
+ * of the loaded properties files or as System parameter. The order of evaluation is the same as with
+ * the <code>categoriesKey</code> (see above).
+ * </p>
+ * <p>
+ * For beans which explicitely need lazy initialization (or not), a meta value can
+ * be defined to overrule/enforce the default behavior:
+ * <pre><meta key="j2:lazy" value="<true|false>"/></pre>
+ * </p>
+ *
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @since 2.2
+ * @version $Id$
+ */
+public class JetspeedBeanDefinitionFilter extends PropertiesLoaderSupport
+{
+ private static Log log = LogFactory.getLog(JetspeedBeanDefinitionFilter.class);
+
+ public static final String SYSTEM_PROPERTY_CATEGORIES_KEY = "JetspeedBeanDefinitionFilter.categoriesKey";
+ public static final String SYSTEM_PROPERTY_DEFAULT_LAZY_INIT = "JetspeedBeanDefinitionFilter.defaultLazyInit";
+
+ public static final String CATEGORY_META_KEY = "j2:cat";
+ public static final String ALIAS_META_KEY = "j2:alias";
+ public static final String LAZY_META_KEY = "j2:lazy";
+
+ private String categoriesKey;
+ private Boolean defaultLazyInit;
+ private Properties props;
+ private Set categories;
+ private boolean initialized;
+
+ public JetspeedBeanDefinitionFilter()
+ {
+ }
+
+ public JetspeedBeanDefinitionFilter(Boolean defaultLazyInit, String categories)
+ {
+ setDefaultLazyInit(defaultLazyInit);
+ setCategories(categories);
+ }
+
+ public JetspeedBeanDefinitionFilter(Boolean defaultLazyInit, Set categories)
+ {
+ setDefaultLazyInit(defaultLazyInit);
+ setCategories(categories);
+ }
+
+ public JetspeedBeanDefinitionFilter(String categoriesKey, Boolean defaultLazyInit)
+ {
+ setCategoriesKey(categoriesKey);
+ setDefaultLazyInit(defaultLazyInit);
+ }
+
+ public JetspeedBeanDefinitionFilter(String propertiesLocation) throws IOException
+ {
+ loadProperties(new String[]{propertiesLocation});
+ }
+
+ public JetspeedBeanDefinitionFilter(String propertiesLocation, String categoriesKey, Boolean defaultLazyInit) throws IOException
+ {
+ this(categoriesKey, defaultLazyInit);
+ loadProperties(new String[]{propertiesLocation});
+ }
+
+ public JetspeedBeanDefinitionFilter(String[] propertiesLocations, String categoriesKey, Boolean defaultLazyInit) throws IOException
+ {
+ this(categoriesKey, defaultLazyInit);
+ loadProperties(propertiesLocations);
+ }
+
+ protected void loadProperties(String[] propertiesLocations) throws IOException
+ {
+ if (propertiesLocations != null)
+ {
+ ResourceLoader resourceLoader = new DefaultResourceLoader();
+ Resource[] resources = new Resource[propertiesLocations.length];
+ for (int i = 0; i < propertiesLocations.length; i++)
+ {
+ resources[i] = resourceLoader.getResource(propertiesLocations[i]);
+ }
+ setLocations(resources);
+ props = new Properties();
+ loadProperties(props);
+
+ // interpolation of property references within properties delimited by '${' and '}'
+ // based on org.apache.maven.plugin.resources.PropertiesUtils
+ HashSet circularRefs = new HashSet();
+ ArrayList visitedProps = new ArrayList();
+ for ( Enumeration n = props.propertyNames(); n.hasMoreElements(); )
+ {
+ String k = (String) n.nextElement();
+ String v = props.getProperty( k );
+ String result = "";
+ String nk, nv;
+ int idx, idx2;
+ visitedProps.clear();
+ visitedProps.add(k);
+
+ while ( ( idx = v.indexOf( "${" ) ) >= 0 )
+ {
+ // append prefix to result
+ result += v.substring( 0, idx );
+
+ // strip prefix from original
+ v = v.substring( idx + 2 );
+
+ // if no matching } then bail
+ if ( ( idx2 = v.indexOf( '}' ) ) < 0 )
+ {
+ break;
+ }
+
+ // strip out the key and resolve it
+ // resolve the key/value for the ${statement}
+ nk = v.substring( 0, idx2 );
+ v = v.substring( idx2 + 1 );
+
+ nv = null;
+
+ if (circularRefs.contains(nk) || visitedProps.contains(nk))
+ {
+ // prevent looping
+ log.error("Circular property reference: "+nk+" encountered for: "+k+". Property value not fully resolved");
+ circularRefs.add(k);
+ }
+ else
+ {
+ nv = props.getProperty( nk );
+
+ // try global environment..
+ if ( nv == null )
+ {
+ nv = System.getProperty( nk );
+ }
+ else
+ {
+ visitedProps.add(nk);
+ }
+ }
+
+ // if the key cannot be resolved,
+ // leave it alone ( and don't parse again )
+ // else prefix the original string with the
+ // resolved property ( so it can be parsed further )
+ // taking recursion into account.
+ if ( nv == null || nv.equals( k ) )
+ {
+ result += "${" + nk + "}";
+ }
+ else
+ {
+ v = nv + v;
+ }
+ }
+ props.setProperty( k, result + v );
+ }
+ }
+ }
+
+ public void setCategoriesKey(String categoriesKey)
+ {
+ this.categoriesKey = categoriesKey;
+ }
+
+ public void setDefaultLazyInit(Boolean defaultLazyInit)
+ {
+ this.defaultLazyInit = defaultLazyInit;
+ }
+
+ public void setCategories(String categories)
+ {
+ if (categories != null && categories.length()>0)
+ {
+ this.categories = new HashSet();
+ StringTokenizer st = new StringTokenizer(categories, " ,;\t");
+ while (st.hasMoreTokens())
+ {
+ this.categories.add(st.nextToken());
+ }
+ }
+ else
+ {
+ this.categories = null;
+ }
+ }
+
+ public void setCategories(Set categories)
+ {
+ this.categories = categories;
+ }
+
+ public void init() throws IllegalStateException
+ {
+ if (!initialized)
+ {
+ initialized = true;
+
+ if (props != null && categories == null)
+ {
+ this.categories = new HashSet();
+ String value = System.getProperty(SYSTEM_PROPERTY_CATEGORIES_KEY);
+ if (value == null && props != null)
+ {
+ value = props.getProperty(SYSTEM_PROPERTY_CATEGORIES_KEY);
+ }
+ if (value != null)
+ {
+ categoriesKey = value;
+ }
+ if (categoriesKey == null || categoriesKey.length() == 0)
+ {
+ throw new IllegalStateException("Required property categoriesKey undefined");
+ }
+ else
+ {
+ String categories = (String)props.get(categoriesKey);
+ if (categories != null && categories.length()>0)
+ {
+ StringTokenizer st = new StringTokenizer(categories, " ,;\t");
+ while (st.hasMoreTokens())
+ {
+ this.categories.add(st.nextToken());
+ }
+ }
+ props = null;
+ }
+ }
+ if (this.categories == null)
+ {
+ this.categories = new HashSet();
+ }
+ String value = System.getProperty(SYSTEM_PROPERTY_DEFAULT_LAZY_INIT);
+ if (value == null && props != null)
+ {
+ value = props.getProperty(SYSTEM_PROPERTY_DEFAULT_LAZY_INIT);
+ }
+ if (value != null)
+ {
+ defaultLazyInit = Boolean.valueOf(value);
+ }
+ }
+ }
+
+ public boolean match(BeanDefinition bd)
+ {
+ String beanCategories = (String)bd.getAttribute(CATEGORY_META_KEY);
+ Boolean lazyInit = defaultLazyInit;
+ boolean matched = true;
+ if (beanCategories != null)
+ {
+ matched = false;
+ StringTokenizer st = new StringTokenizer(beanCategories, " ,;\t");
+ while (st.hasMoreTokens())
+ {
+ if (categories.contains(st.nextToken()))
+ {
+ matched = true;
+ break;
+ }
+ }
+ }
+ if (matched)
+ {
+ if (bd instanceof AbstractBeanDefinition)
+ {
+ AbstractBeanDefinition abd = (AbstractBeanDefinition)bd;
+ String j2Lazy = (String)bd.getAttribute(LAZY_META_KEY);
+ if (j2Lazy != null)
+ {
+ lazyInit = Boolean.valueOf((String)bd.getAttribute(LAZY_META_KEY));
+ }
+ if (lazyInit != null)
+ {
+ abd.setLazyInit(lazyInit.booleanValue());
+ }
+ }
+ }
+ return matched;
+ }
+
+ public void registerDynamicAlias(BeanDefinitionRegistry registry, String beanName, BeanDefinition bd)
+ {
+ String alias = (String)bd.getAttribute(ALIAS_META_KEY);
+ if (alias != null && !alias.equals(beanName))
+ {
+ if (registry.isBeanNameInUse(alias))
+ {
+ String src = "";
+ if (bd.getSource() != null)
+ {
+ src = "("+bd.getSource().toString()+")";
+ }
+ throw new BeanDefinitionValidationException("j2:alias '"+alias+"' for bean '"+beanName+"' already in use "+src);
+ }
+ registry.registerAlias(beanName, alias);
+ }
+ }
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/JetspeedBeanDefinitionFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/JetspeedBeanDefinitionFilter.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/main/java/org/apache/jetspeed/components/JetspeedBeanDefinitionFilter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org