You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2006/11/14 12:08:31 UTC
svn commit: r474730 - in /lenya/trunk/src:
java/org/apache/lenya/cms/cocoon/source/
java/org/apache/lenya/cms/publication/templating/
modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/
pubs/default/config/ac/ webapp/lenya/config/cocoon...
Author: andreas
Date: Tue Nov 14 03:08:30 2006
New Revision: 474730
URL: http://svn.apache.org/viewvc?view=rev&rev=474730
Log:
Introduce AggregatingSource, use for aggregating of usecase policies
Added:
lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java
lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingSource.java
lenya/trunk/src/java/org/apache/lenya/cms/publication/templating/AllExistingSourceResolver.java
lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/aggregate-fallback.xconf
Modified:
lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseAuthorizerImpl.java
lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseRolesBuilder.java
lenya/trunk/src/pubs/default/config/ac/ac.xconf
Added: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java?view=auto&rev=474730
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java (added)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java Tue Nov 14 03:08:30 2006
@@ -0,0 +1,145 @@
+/*
+ * 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.lenya.cms.cocoon.source;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceFactory;
+import org.apache.excalibur.source.SourceUtil;
+import org.apache.excalibur.source.URIAbsolutizer;
+import org.apache.lenya.cms.publication.DocumentFactory;
+import org.apache.lenya.cms.publication.DocumentUtil;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.cms.publication.PublicationManager;
+import org.apache.lenya.cms.publication.URLInformation;
+import org.apache.lenya.cms.publication.templating.AllExistingSourceResolver;
+import org.apache.lenya.cms.publication.templating.PublicationTemplateManager;
+
+/**
+ * @see org.apache.lenya.cms.publication.templating.AggregatingVisitor
+ */
+public class AggregatingFallbackSourceFactory extends AbstractLogEnabled implements SourceFactory,
+ Serviceable, Contextualizable, URIAbsolutizer {
+
+ public Source getSource(final String location, Map parameters) throws IOException,
+ MalformedURLException {
+
+ // Remove the protocol and the first '//'
+ int pos = location.indexOf("://");
+
+ if (pos == -1) {
+ throw new RuntimeException("The location [" + location
+ + "] does not contain the string '://'");
+ }
+
+ String path = location.substring(pos + 3);
+ String publicationId = null;
+
+ // allow for template-fallback://{pubid}//{path} for the sake of the
+ // cocoon use-store
+ if (path.indexOf("//") > 1) {
+ pos = path.indexOf("//");
+ publicationId = path.substring(0, pos);
+ path = path.substring(pos + 2, path.length());
+ }
+
+ if (path.length() == 0) {
+ throw new RuntimeException("The path after the protocol must not be empty!");
+ }
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Location: [" + location + "]");
+ getLogger().debug("Path: [" + path + "]");
+ }
+
+ PublicationManager pubMgr = null;
+ PublicationTemplateManager templateManager = null;
+ try {
+ templateManager = (PublicationTemplateManager) this.manager
+ .lookup(PublicationTemplateManager.ROLE);
+
+ Request request = ContextHelper.getRequest(this.context);
+
+ if (publicationId == null) {
+ String webappUrl = request.getRequestURI().substring(
+ request.getContextPath().length());
+
+ URLInformation info = new URLInformation(webappUrl);
+ publicationId = info.getPublicationId();
+ }
+
+ pubMgr = (PublicationManager) this.manager.lookup(PublicationManager.ROLE);
+ DocumentFactory factory = DocumentUtil.getDocumentFactory(this.manager, request);
+ Publication pub = pubMgr.getPublication(factory, publicationId);
+
+ String[] uris;
+
+ if (pub.exists()) {
+ AllExistingSourceResolver resolver = new AllExistingSourceResolver();
+ templateManager.visit(pub, path, resolver);
+ uris = resolver.getUris();
+ } else {
+ uris = new String[0];
+ }
+
+ return new AggregatingSource(location, uris, this.manager);
+
+ } catch (Exception e) {
+ throw new RuntimeException("Resolving path [" + location + "] failed: ", e);
+ } finally {
+ if (templateManager != null) {
+ this.manager.release(templateManager);
+ }
+ if (pubMgr != null) {
+ this.manager.release(pubMgr);
+ }
+ }
+ }
+
+ public void release(Source source) {
+ }
+
+ private ServiceManager manager;
+
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ }
+
+ private Context context;
+
+ public void contextualize(Context context) throws ContextException {
+ this.context = context;
+ }
+
+ public String absolutize(String baseURI, String location) {
+ return SourceUtil.absolutize(baseURI, location, true);
+ }
+
+}
Added: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingSource.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingSource.java?view=auto&rev=474730
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingSource.java (added)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingSource.java Tue Nov 14 03:08:30 2006
@@ -0,0 +1,174 @@
+package org.apache.lenya.cms.cocoon.source;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.AggregatedValidity;
+import org.apache.lenya.xml.DocumentHelper;
+import org.apache.lenya.xml.NamespaceHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ *
+ */
+public class AggregatingSource implements Source {
+
+ private String uri;
+ private String[] sourceUris;
+ private ServiceManager manager;
+
+ /**
+ * @param uri
+ * @param uris
+ * @param manager
+ */
+ public AggregatingSource(String uri, String[] uris, ServiceManager manager) {
+ this.manager = manager;
+ this.sourceUris = uris;
+ this.uri = uri;
+ }
+
+ protected void loadDom() {
+ try {
+ for (int i = 0; i < sourceUris.length; i++) {
+ Document sourceDom = SourceUtil.readDOM(sourceUris[i], manager);
+
+ if (sourceDom == null) {
+ throw new RuntimeException("The source [" + sourceUris[i] + "] doesn't contain XML.");
+ }
+
+ Element docElement = sourceDom.getDocumentElement();
+ if (this.dom == null) {
+ String namespaceUri = docElement.getNamespaceURI();
+ String prefix = docElement.getPrefix();
+ String localName = docElement.getLocalName();
+
+ if (namespaceUri == null || prefix == null) {
+ this.dom = DocumentHelper.createDocument(null, localName, null);
+ }
+ else {
+ NamespaceHelper helper = new NamespaceHelper(namespaceUri, prefix, localName);
+ this.dom = helper.getDocument();
+ }
+ }
+
+ Element[] elements = DocumentHelper.getChildren(docElement);
+ for (int e = 0; e < elements.length; e++) {
+ Element clone = (Element) this.dom.importNode(elements[e], true);
+ this.dom.getDocumentElement().appendChild(clone);
+ }
+ }
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Document dom;
+ private byte[] data;
+
+ protected Document getDom() {
+ if (this.dom == null) {
+ loadDom();
+ }
+ return this.dom;
+ }
+
+ protected byte[] getData() {
+ if (this.data == null) {
+ Document dom = getDom();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ DocumentHelper.writeDocument(dom, out);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ this.data = out.toByteArray();
+ }
+ return this.data;
+ }
+
+ public boolean exists() {
+ return getData().length > 0;
+ }
+
+ public long getContentLength() {
+ return getData().length;
+ }
+
+ public InputStream getInputStream() throws IOException, SourceNotFoundException {
+ if (!exists()) {
+ throw new RuntimeException(this + " does not exist!");
+ }
+ return new ByteArrayInputStream(this.data);
+ }
+
+ public long getLastModified() {
+ long lastModified = 0;
+ for (int i = 0; i < this.sourceUris.length; i++) {
+ try {
+ lastModified = Math
+ .max(lastModified, SourceUtil.getLastModified(sourceUris[i], this.manager));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return lastModified;
+ }
+
+ public String getMimeType() {
+ return "application/xml";
+ }
+
+ public String getScheme() {
+ return "aggregate-template";
+ }
+
+ public String getURI() {
+ return this.uri;
+ }
+
+ private SourceValidity validity;
+
+ public SourceValidity getValidity() {
+ if (this.validity == null) {
+ AggregatedValidity aggregatedValidity = new AggregatedValidity();
+ for (int i = 0; i < this.sourceUris.length; i++) {
+ SourceResolver resolver = null;
+ Source source = null;
+ try {
+ resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+ source = resolver.resolveURI(this.sourceUris[i]);
+ aggregatedValidity.add(source.getValidity());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ finally {
+ if (resolver != null) {
+ if (source != null) {
+ resolver.release(source);
+ }
+ this.manager.release(resolver);
+ }
+ }
+ }
+ this.validity = aggregatedValidity;
+ }
+ return this.validity;
+ }
+
+ public void refresh() {
+ this.dom = null;
+ this.data = null;
+ }
+
+}
Added: lenya/trunk/src/java/org/apache/lenya/cms/publication/templating/AllExistingSourceResolver.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/publication/templating/AllExistingSourceResolver.java?view=auto&rev=474730
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/publication/templating/AllExistingSourceResolver.java (added)
+++ lenya/trunk/src/java/org/apache/lenya/cms/publication/templating/AllExistingSourceResolver.java Tue Nov 14 03:08:30 2006
@@ -0,0 +1,45 @@
+/*
+ * 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.lenya.cms.publication.templating;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.excalibur.source.Source;
+
+/**
+ * Source visitor to obtain all existing sources.
+ */
+public class AllExistingSourceResolver implements SourceVisitor {
+
+ public void visit(Source source) {
+ if (source.exists()) {
+ this.uris.add(source.getURI());
+ }
+ }
+
+ private List uris = new ArrayList();
+
+ /**
+ * @return All existing source URIs.
+ */
+ public String[] getUris() {
+ return (String[]) this.uris.toArray(new String[this.uris.size()]);
+ }
+
+}
Modified: lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseAuthorizerImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseAuthorizerImpl.java?view=diff&rev=474730&r1=474729&r2=474730
==============================================================================
--- lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseAuthorizerImpl.java (original)
+++ lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseAuthorizerImpl.java Tue Nov 14 03:08:30 2006
@@ -20,7 +20,9 @@
import java.io.File;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.configuration.Configuration;
@@ -64,28 +66,32 @@
return this.cache;
}
+ private Map pubId2configUri = new HashMap();
+
/**
- * Returns the source URI of the usecase role configuration file for a certain publication.
- * TODO: This method seems to be called many times. Wouldn't it make sense to cache it somehow
- * ...?
+ * Returns the source URI of the usecase role configuration file for a
+ * certain publication.
*
* @param publication The publication.
- * @param requestURI The request URI.
* @return A string representing a URI.
*/
- protected String getConfigurationURI(Publication publication, String requestURI) {
- String configURI = null;
- try {
- Configuration config = getConfiguration(publication);
- Configuration[] authorizerConfigs = config.getChildren("authorizer");
- for (int i = 0; i < authorizerConfigs.length; i++) {
- if (authorizerConfigs[i].getAttribute("type").equals("usecase")) {
- Configuration paraConfig = authorizerConfigs[i].getChild("parameter");
- configURI = paraConfig.getAttribute("value");
+ protected String getConfigurationURI(Publication publication) {
+
+ String configURI = (String) this.pubId2configUri.get(publication.getId());
+ if (configURI == null) {
+ try {
+ Configuration config = getConfiguration(publication);
+ Configuration[] authorizerConfigs = config.getChildren("authorizer");
+ for (int i = 0; i < authorizerConfigs.length; i++) {
+ if (authorizerConfigs[i].getAttribute("type").equals("usecase")) {
+ Configuration paraConfig = authorizerConfigs[i].getChild("parameter");
+ configURI = paraConfig.getAttribute("value");
+ this.pubId2configUri.put(publication.getId(), configURI);
+ }
}
+ } catch (Exception e) {
+ getLogger().error(e.getMessage(), e);
}
- } catch (Exception e) {
- getLogger().error(e.getMessage(), e);
}
return configURI;
}
@@ -109,14 +115,12 @@
_configurationUri = getConfigurationURI();
} else {
Publication publication = PublicationUtil.getPublication(this.manager, request);
- _configurationUri = getConfigurationURI(publication, request.getRequestURI());
+ _configurationUri = getConfigurationURI(publication);
}
Role[] roles = PolicyUtil.getRoles(request);
- authorized = authorizeUsecase(usecase,
- roles,
- _configurationUri,
- request.getRequestURI());
+ authorized = authorizeUsecase(usecase, roles, _configurationUri, request
+ .getRequestURI());
} else {
getLogger().debug("No usecase to authorize. Granting access.");
}
@@ -140,7 +144,8 @@
*
* @param usecase The usecase ID.
* @param roles The roles of the current identity.
- * @param _configurationUri The URI to retrieve the policy configuration from.
+ * @param _configurationUri The URI to retrieve the policy configuration
+ * from.
* @param requestURI The request URI.
* @return A boolean value.
* @throws AccessControlException when something went wrong.
@@ -171,8 +176,10 @@
int i = 0;
while (!authorized && i < roles.length) {
authorized = usecaseRoleIds.contains(roles[i].getId());
- getLogger().debug("Authorization for role [" + roles[i].getId() + "] is ["
- + authorized + "]");
+ getLogger()
+ .debug(
+ "Authorization for role [" + roles[i].getId() + "] is ["
+ + authorized + "]");
i++;
}
} else {
@@ -231,18 +238,16 @@
*/
public boolean authorizeUsecase(String usecase, Role[] roles, Publication publication,
String requestURI) throws AccessControlException {
- return authorizeUsecase(usecase,
- roles,
- getConfigurationURI(publication, requestURI),
- requestURI);
+ return authorizeUsecase(usecase, roles, getConfigurationURI(publication), requestURI);
}
protected boolean authorize(Request request, String webappUrl) throws AccessControlException {
return authorize(request);
}
- protected static final String AC_CONFIGURATION_FILE = "config/ac/ac.xconf".replace('/', File.separatorChar);
-
+ protected static final String AC_CONFIGURATION_FILE = "config/ac/ac.xconf".replace('/',
+ File.separatorChar);
+
/**
* Retrieves access control configuration of a specific publication.
* @param publication The publication.
@@ -254,7 +259,8 @@
if (configurationFile.isFile()) {
try {
- Configuration configuration = new DefaultConfigurationBuilder().buildFromFile(configurationFile);
+ Configuration configuration = new DefaultConfigurationBuilder()
+ .buildFromFile(configurationFile);
return configuration;
} catch (Exception e) {
throw new AccessControlException(e);
Modified: lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseRolesBuilder.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseRolesBuilder.java?view=diff&rev=474730&r1=474729&r2=474730
==============================================================================
--- lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseRolesBuilder.java (original)
+++ lenya/trunk/src/modules-core/usecase-impl/java/src/org/apache/lenya/cms/ac/usecase/UsecaseRolesBuilder.java Tue Nov 14 03:08:30 2006
@@ -32,7 +32,7 @@
/**
* Builder for usecase roles.
- *
+ *
* @version $Id$
*/
public class UsecaseRolesBuilder implements InputStreamBuilder {
@@ -57,24 +57,25 @@
}
assert document.getDocumentElement().getLocalName().equals(USECASES_ELEMENT);
- NamespaceHelper helper =
- new NamespaceHelper(
- AccessController.NAMESPACE,
- AccessController.DEFAULT_PREFIX,
- document);
+ NamespaceHelper helper = new NamespaceHelper(AccessController.NAMESPACE,
+ AccessController.DEFAULT_PREFIX, document);
- Element[] usecaseElements =
- helper.getChildren(document.getDocumentElement(), USECASE_ELEMENT);
+ Element[] usecaseElements = helper.getChildren(document.getDocumentElement(),
+ USECASE_ELEMENT);
for (int i = 0; i < usecaseElements.length; i++) {
String usecaseId = usecaseElements[i].getAttribute(ID_ATTRIBUTE);
- Element[] roleElements = helper.getChildren(usecaseElements[i], ROLE_ELEMENT);
- Set roleIds = new HashSet();
- for (int j = 0; j < roleElements.length; j++) {
- String roleId = roleElements[j].getAttribute(ID_ATTRIBUTE);
- roleIds.add(roleId);
+
+ // add roles only if not overridden by child publication
+ if (!usecaseRoles.hasRoles(usecaseId)) {
+ Element[] roleElements = helper.getChildren(usecaseElements[i], ROLE_ELEMENT);
+ Set roleIds = new HashSet();
+ for (int j = 0; j < roleElements.length; j++) {
+ String roleId = roleElements[j].getAttribute(ID_ATTRIBUTE);
+ roleIds.add(roleId);
+ }
+ String[] roleIdArray = (String[]) roleIds.toArray(new String[roleIds.size()]);
+ usecaseRoles.setRoles(usecaseId, roleIdArray);
}
- String[] roleIdArray = (String[]) roleIds.toArray(new String[roleIds.size()]);
- usecaseRoles.setRoles(usecaseId, roleIdArray);
}
return usecaseRoles;
}
Modified: lenya/trunk/src/pubs/default/config/ac/ac.xconf
URL: http://svn.apache.org/viewvc/lenya/trunk/src/pubs/default/config/ac/ac.xconf?view=diff&rev=474730&r1=474729&r2=474730
==============================================================================
--- lenya/trunk/src/pubs/default/config/ac/ac.xconf (original)
+++ lenya/trunk/src/pubs/default/config/ac/ac.xconf Tue Nov 14 03:08:30 2006
@@ -39,7 +39,7 @@
<authorizer type="policy"/>
<authorizer type="usecase">
- <parameter name="configuration" value="fallback://config/ac/usecase-policies.xml"/>
+ <parameter name="configuration" value="aggregate-fallback://config/ac/usecase-policies.xml"/>
</authorizer>
</access-controller>
Added: lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/aggregate-fallback.xconf
URL: http://svn.apache.org/viewvc/lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/aggregate-fallback.xconf?view=auto&rev=474730
==============================================================================
--- lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/aggregate-fallback.xconf (added)
+++ lenya/trunk/src/webapp/lenya/config/cocoon-xconf/source-factories/aggregate-fallback.xconf Tue Nov 14 03:08:30 2006
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+
+<!-- $Id: usecases-workflow-deactivate.xconf 348547 2005-11-23 20:13:01Z chestnut $ -->
+<!--
+ This file defines the publication specific use-cases
+-->
+
+ <xconf xpath="/cocoon/source-factories"
+ unless="/cocoon/source-factories/component-instance[@name = 'aggregate-fallback']">
+ <component-instance class="org.apache.lenya.cms.cocoon.source.AggregatingFallbackSourceFactory"
+ logger="lenya.source.aggregatefallback" name="aggregate-fallback"/>
+ </xconf>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org