blob: f08be25ad8dcd0114a62c9701b0ff523c9dcf000 [file] [log] [blame]
/*
* 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.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.cocoon.processing.ProcessInfoProvider;
import org.apache.cocoon.spring.configurator.WebAppContextUtils;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.store.impl.MRUMemoryStore;
import org.apache.lenya.cms.module.Module;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.Session;
import org.apache.lenya.cms.publication.URLInformation;
import org.apache.lenya.cms.publication.templating.AllExistingSourceResolver;
import org.apache.lenya.util.ServletHelper;
/**
* <p>
* Aggregate all existing fallback sources by adding their XML content under the document element of
* the first encountered source. The document element of all subsequent sources is stripped.
* </p>
* <p>
* The fallback sources are resolved in bottom-up order, i.e.
* </p>
* <ul>
* <li>current publication</li>
* <li>template of the current publication</li>
* <li>template of the template publication</li>
* <li>...</li>
* <li>core</li>
* </ul>
* <p>
* If one of the fallback sources is not a well-formed XML document, a RuntimeException is thrown.
* </p>
*/
public class AggregatingFallbackSourceFactory extends FallbackSourceFactory {
/**
* @see org.apache.excalibur.source.SourceFactory#getSource(java.lang.String, java.util.Map)
*/
public Source getSource(final String location, Map parameters) throws IOException,
MalformedURLException {
String[] uris;
if (useCache()) {
MRUMemoryStore store = getStore();
final String cacheKey = getCacheKey(getPublicationId(), location);
final String[] cachedUris = (String[]) store.get(cacheKey);
if (cachedUris == null) {
uris = findUris(location, parameters);
store.hold(cacheKey, uris);
if (getLogger().isDebugEnabled()) {
getLogger()
.debug(
"No cached source URI for key " + cacheKey
+ ", caching resolved URIs.");
}
} else {
uris = cachedUris;
if (getLogger().isDebugEnabled()) {
getLogger().debug("Using cached source URIs for key " + cacheKey);
}
}
} else {
uris = findUris(location, parameters);
}
return new AggregatingSource(location, uris, getSourceResolver());
}
protected String[] findUris(final String location, Map parameters) throws IOException,
MalformedURLException {
FallbackUri uri = new FallbackUri(location);
String pubId = uri.getPubId();
String path = uri.getPath();
try {
final ProcessInfoProvider processInfo = (ProcessInfoProvider) WebAppContextUtils
.getCurrentWebApplicationContext().getBean(ProcessInfoProvider.ROLE);
HttpServletRequest request = processInfo.getRequest();
if (pubId == null) {
String webappUrl = ServletHelper.getWebappURI(request);
URLInformation info = new URLInformation(webappUrl);
pubId = info.getPublicationId();
}
Session session = getRepository().getSession(request);
String[] uris;
if (session.existsPublication(pubId)) {
Publication pub = session.getPublication(pubId);
AllExistingSourceResolver resolver = new AllExistingSourceResolver();
getTemplateManager().visit(pub, path, resolver);
uris = resolver.getUris();
} else {
uris = new String[0];
}
List allUris = new ArrayList();
allUris.addAll(Arrays.asList(uris));
String contextSourceUri = null;
if (path.startsWith("lenya/modules/")) {
final String moduleShortcut = path.split("/")[2];
Module module = (Module) getModules().get(moduleShortcut);
final String modulePath = path.substring(("lenya/modules/" + moduleShortcut)
.length());
contextSourceUri = module.getBaseUri() + modulePath;
} else {
contextSourceUri = "context://" + path;
}
if (org.apache.lenya.cms.cocoon.source.SourceUtil.exists(contextSourceUri,
getSourceResolver())) {
allUris.add(contextSourceUri);
}
return (String[]) allUris.toArray(new String[allUris.size()]);
} catch (Exception e) {
throw new RuntimeException("Resolving path [" + location + "] failed: ", e);
}
}
}