blob: 46d72e72142a825fb47e0a53ccf437f6a37a88ae [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed 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.cocoon.components.profiler;
import java.io.IOException;
import java.util.Iterator;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.sitemap.SitemapModelComponent;
import org.apache.cocoon.transformation.Transformer;
import org.apache.cocoon.xml.XMLConsumer;
import org.apache.cocoon.xml.XMLProducer;
import org.xml.sax.SAXException;
/**
* Special version of the NonCachingProcessingPipeline that supports capturing
* the SAX-events that go through it and stores the result in the
* ProfilerData.
*
* @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
* @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
* @author <a href="mailto:bruno@outerthought.org">Bruno Dumon</a>
* @version CVS $Id: ProfilingNonCachingProcessingPipeline.java,v 1.6 2004/03/05 13:02:20 bdelacretaz Exp $
*/
public class ProfilingNonCachingProcessingPipeline
extends NonCachingProcessingPipeline implements Disposable {
private Profiler profiler;
private ProfilerData data = null;
private int index = 0;
/**
* Composable
*
* @param manager
*/
public void compose(ComponentManager manager) throws ComponentException {
super.compose(manager);
this.profiler = (Profiler) manager.lookup(Profiler.ROLE);
}
/**
* Disposable
*/
public void dispose() {
if (this.profiler!=null) {
this.manager.release(this.profiler);
this.profiler = null;
}
}
/**
* Recyclable
*/
public void recycle() {
this.data = null;
this.index = 0;
super.recycle();
}
/**
* Set the generator that will be used as the initial step in the pipeline.
* The generator role is given : the actual <code>Generator</code> is fetched
* from the latest <code>ComponentManager</code> given by <code>compose()</code>
* or <code>recompose()</code>.
*
* @param role the generator role in the component manager.
* @param source the source where to produce XML from, or <code>null</code> if no
* source is given.
* @param param the parameters for the generator.
* @param hintParam
* @throws ProcessingException if the generator couldn't be obtained.
*/
public void setGenerator(String role, String source, Parameters param,
Parameters hintParam)
throws ProcessingException {
super.setGenerator(role, source, param, hintParam);
if (this.data==null) {
this.data = new ProfilerData();
}
this.data.addComponent(super.generator, role, source);
}
/**
* Add a transformer at the end of the pipeline.
* The transformer role is given : the actual <code>Transformer</code> is fetched
* from the latest <code>ComponentManager</code> given by <code>compose()</code>
* or <code>recompose()</code>.
*
* @param role the transformer role in the component manager.
* @param source the source used to setup the transformer (e.g. XSL file), or
* <code>null</code> if no source is given.
* @param param the parameters for the transfomer.
* @param hintParam
* @throws ProcessingException if the generator couldn't be obtained.
*/
public void addTransformer(String role, String source, Parameters param,
Parameters hintParam)
throws ProcessingException {
super.addTransformer(role, source, param, hintParam);
if (this.data==null) {
this.data = new ProfilerData();
}
this.data.addComponent(super.transformers.get(super.transformers.size()-
1), role, source);
}
/**
* Set the serializer for this pipeline
*
* @param role
* @param source
* @param param
* @param hintParam
* @param mimeType
*/
public void setSerializer(String role, String source, Parameters param,
Parameters hintParam,
String mimeType) throws ProcessingException {
super.setSerializer(role, source, param, hintParam, mimeType);
if (this.data==null) {
this.data = new ProfilerData();
}
this.data.addComponent(super.serializer, role, source);
}
/**
* Set the reader for this pipeline
*
* @param role
* @param source
* @param param
* @param mimeType
*/
public void setReader(String role, String source, Parameters param,
String mimeType) throws ProcessingException {
super.setReader(role, source, param, mimeType);
if (this.data==null) {
this.data = new ProfilerData();
}
this.data.addComponent(super.reader, role, source);
}
/**
* Setup pipeline components.
*
* @param environment
*/
protected void setupPipeline(Environment environment)
throws ProcessingException {
try {
// setup the generator
long time = System.currentTimeMillis();
this.generator.setup(environment, environment.getObjectModel(),
generatorSource, generatorParam);
this.data.setSetupTime(0, System.currentTimeMillis()-time);
Iterator transformerItt = this.transformers.iterator();
Iterator transformerSourceItt = this.transformerSources.iterator();
Iterator transformerParamItt = this.transformerParams.iterator();
int index = 1;
while (transformerItt.hasNext()) {
Transformer trans = (Transformer) transformerItt.next();
time = System.currentTimeMillis();
trans.setup(environment, environment.getObjectModel(),
(String) transformerSourceItt.next(),
(Parameters) transformerParamItt.next());
this.data.setSetupTime(index++,
System.currentTimeMillis()-time);
}
time = System.currentTimeMillis();
if (this.serializer instanceof SitemapModelComponent) {
((SitemapModelComponent)this.serializer).setup(
environment,
environment.getObjectModel(),
serializerSource,
serializerParam
);
}
this.data.setSetupTime(index++, System.currentTimeMillis()-time);
String mimeType = this.serializer.getMimeType();
if (mimeType!=null) {
// we have a mimeType from the component itself
environment.setContentType(mimeType);
} else if (serializerMimeType!=null) {
// there was a mimeType specified in the sitemap pipeline
environment.setContentType(serializerMimeType);
} else if (this.sitemapSerializerMimeType!=null) {
// use the mimeType specified in the sitemap component declaration
environment.setContentType(this.sitemapSerializerMimeType);
} else {
// No mimeType available
String message = "Unable to determine MIME type for "+
environment.getURIPrefix()+"/"+
environment.getURI();
throw new ProcessingException(message);
}
} catch (SAXException e) {
throw new ProcessingException("Could not setup pipeline.", e);
} catch (IOException e) {
throw new ProcessingException("Could not setup pipeline.", e);
}
}
/**
* Process the given <code>Environment</code>, producing the output.
*
* @param environment
*
* @return true on success
*/
public boolean process(Environment environment)
throws ProcessingException {
this.index = 0;
if (this.data!=null) {
// Capture environment info
this.data.setEnvironmentInfo(new EnvironmentInfo(environment));
// Execute pipeline
long time = System.currentTimeMillis();
boolean result = super.process(environment);
this.data.setTotalTime(System.currentTimeMillis()-time);
// Report
profiler.addResult(environment.getURI(), this.data);
return result;
} else {
getLogger().warn("Profiler Data havn't any components to measure");
return super.process(environment);
}
}
/**
* Connect the next component
*
* @param environment
* @param producer
* @param consumer
*/
protected void connect(Environment environment, XMLProducer producer,
XMLConsumer consumer) throws ProcessingException {
ProfilingXMLPipe connector = new ProfilingXMLPipe();
connector.setup(this.index, this.data);
this.index++;
super.connect(environment, producer, connector);
super.connect(environment, connector, consumer);
}
}