blob: 38c4bedca4c3ad954d03e3e67ec5080c5d88d872 [file] [log] [blame]
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.cocoon.components.source.impl.MultiSourceValidity;
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.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 = (String[])uris.clone();
this.uri = uri;
}
public String toString() {
return getURI();
}
protected void loadDom() {
try {
for (int i = 0; i < sourceUris.length; i++) {
Document sourceDom = SourceUtil.readDOM(sourceUris[i], this.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) {
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();
if (dom != null) {
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 this.sourceUris.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(getData());
}
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) {
SourceResolver resolver = null;
try {
resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
MultiSourceValidity aggregatedValidity = new MultiSourceValidity(resolver, 0);
for (int i = 0; i < this.sourceUris.length; i++) {
Source source = null;
try {
source = resolver.resolveURI(this.sourceUris[i]);
aggregatedValidity.addSource(source);
} finally {
if (source != null) {
resolver.release(source);
}
}
}
aggregatedValidity.close();
this.validity = aggregatedValidity;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (resolver != null) {
this.manager.release(resolver);
}
}
}
return this.validity;
}
public void refresh() {
this.dom = null;
this.data = null;
this.validity = null;
}
}