001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.profiler;
018:
019: import java.io.IOException;
020: import java.util.Iterator;
021:
022: import org.apache.avalon.framework.activity.Disposable;
023: import org.apache.avalon.framework.component.ComponentException;
024: import org.apache.avalon.framework.component.ComponentManager;
025: import org.apache.avalon.framework.parameters.Parameters;
026: import org.apache.cocoon.ProcessingException;
027: import org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline;
028: import org.apache.cocoon.environment.Environment;
029: import org.apache.cocoon.sitemap.SitemapModelComponent;
030: import org.apache.cocoon.transformation.Transformer;
031: import org.apache.cocoon.xml.XMLConsumer;
032: import org.apache.cocoon.xml.XMLProducer;
033: import org.xml.sax.SAXException;
034:
035: /**
036: * Special version of the NonCachingProcessingPipeline that supports capturing
037: * the SAX-events that go through it and stores the result in the
038: * ProfilerData.
039: *
040: * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
041: * @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
042: * @author <a href="mailto:bruno@outerthought.org">Bruno Dumon</a>
043: * @version $Id: ProfilingNonCachingProcessingPipeline.java 433543 2006-08-22 06:22:54Z crossley $
044: */
045: public class ProfilingNonCachingProcessingPipeline extends
046: NonCachingProcessingPipeline implements Disposable {
047:
048: private Profiler profiler;
049:
050: private ProfilerData data;
051:
052: private int index;
053:
054: /**
055: * Composable
056: *
057: * @param manager
058: */
059: public void compose(ComponentManager manager)
060: throws ComponentException {
061: super .compose(manager);
062: this .profiler = (Profiler) manager.lookup(Profiler.ROLE);
063: }
064:
065: /**
066: * Disposable
067: */
068: public void dispose() {
069: if (this .profiler != null) {
070: this .manager.release(this .profiler);
071: this .profiler = null;
072: }
073: }
074:
075: /**
076: * Recyclable
077: */
078: public void recycle() {
079: this .data = null;
080: this .index = 0;
081: super .recycle();
082: }
083:
084: /**
085: * Set the generator that will be used as the initial step in the pipeline.
086: * The generator role is given : the actual <code>Generator</code> is fetched
087: * from the latest <code>ComponentManager</code> given by <code>compose()</code>
088: * or <code>recompose()</code>.
089: *
090: * @param role the generator role in the component manager.
091: * @param source the source where to produce XML from, or <code>null</code> if no
092: * source is given.
093: * @param param the parameters for the generator.
094: * @param hintParam
095: * @throws ProcessingException if the generator couldn't be obtained.
096: */
097: public void setGenerator(String role, String source,
098: Parameters param, Parameters hintParam)
099: throws ProcessingException {
100:
101: super .setGenerator(role, source, param, hintParam);
102:
103: if (this .data == null) {
104: this .data = new ProfilerData();
105: }
106: this .data.addComponent(super .generator, role, source);
107: }
108:
109: /**
110: * Add a transformer at the end of the pipeline.
111: * The transformer role is given : the actual <code>Transformer</code> is fetched
112: * from the latest <code>ComponentManager</code> given by <code>compose()</code>
113: * or <code>recompose()</code>.
114: *
115: * @param role the transformer role in the component manager.
116: * @param source the source used to setup the transformer (e.g. XSL file), or
117: * <code>null</code> if no source is given.
118: * @param param the parameters for the transfomer.
119: * @param hintParam
120: * @throws ProcessingException if the generator couldn't be obtained.
121: */
122: public void addTransformer(String role, String source,
123: Parameters param, Parameters hintParam)
124: throws ProcessingException {
125:
126: super .addTransformer(role, source, param, hintParam);
127:
128: if (this .data == null) {
129: this .data = new ProfilerData();
130: }
131: this .data.addComponent(super .transformers
132: .get(super .transformers.size() - 1), role, source);
133: }
134:
135: /**
136: * Set the serializer for this pipeline
137: *
138: * @param role
139: * @param source
140: * @param param
141: * @param hintParam
142: * @param mimeType
143: */
144: public void setSerializer(String role, String source,
145: Parameters param, Parameters hintParam, String mimeType)
146: throws ProcessingException {
147:
148: super .setSerializer(role, source, param, hintParam, mimeType);
149:
150: if (this .data == null) {
151: this .data = new ProfilerData();
152: }
153: this .data.addComponent(super .serializer, role, source);
154: }
155:
156: /**
157: * Set the reader for this pipeline
158: *
159: * @param role
160: * @param source
161: * @param param
162: * @param mimeType
163: */
164: public void setReader(String role, String source, Parameters param,
165: String mimeType) throws ProcessingException {
166:
167: super .setReader(role, source, param, mimeType);
168:
169: if (this .data == null) {
170: this .data = new ProfilerData();
171: }
172: this .data.addComponent(super .reader, role, source);
173: }
174:
175: /**
176: * Setup pipeline components.
177: *
178: * @param environment
179: */
180: protected void setupPipeline(Environment environment)
181: throws ProcessingException {
182: try {
183: // Setup the generator
184: long time = System.currentTimeMillis();
185: this .generator.setup(environment, environment
186: .getObjectModel(), generatorSource, generatorParam);
187: this .data
188: .setSetupTime(0, System.currentTimeMillis() - time);
189:
190: Iterator transformerItt = this .transformers.iterator();
191: Iterator transformerSourceItt = this .transformerSources
192: .iterator();
193: Iterator transformerParamItt = this .transformerParams
194: .iterator();
195:
196: // Setup transformers
197: int index = 1;
198: while (transformerItt.hasNext()) {
199: Transformer trans = (Transformer) transformerItt.next();
200:
201: time = System.currentTimeMillis();
202: trans.setup(environment, environment.getObjectModel(),
203: (String) transformerSourceItt.next(),
204: (Parameters) transformerParamItt.next());
205: this .data.setSetupTime(index++, System
206: .currentTimeMillis()
207: - time);
208: }
209:
210: // Setup serializer
211: time = System.currentTimeMillis();
212: if (this .serializer instanceof SitemapModelComponent) {
213: ((SitemapModelComponent) this .serializer).setup(
214: environment, environment.getObjectModel(),
215: serializerSource, serializerParam);
216: }
217: this .data.setSetupTime(index++, System.currentTimeMillis()
218: - time);
219:
220: setMimeTypeForSerializer(environment);
221: } catch (SAXException e) {
222: throw new ProcessingException("Could not setup pipeline.",
223: e);
224: } catch (IOException e) {
225: throw new ProcessingException("Could not setup pipeline.",
226: e);
227: }
228: }
229:
230: /**
231: * Process the given <code>Environment</code>, producing the output.
232: *
233: * @param environment
234: *
235: * @return true on success
236: */
237: public boolean process(Environment environment)
238: throws ProcessingException {
239:
240: this .index = 0;
241: if (this .data != null) {
242: // Capture environment info
243: this .data.setEnvironmentInfo(new EnvironmentInfo(
244: environment));
245:
246: // Execute pipeline
247: long time = System.currentTimeMillis();
248: boolean result = super .process(environment);
249:
250: this .data.setTotalTime(System.currentTimeMillis() - time);
251:
252: // Report
253: profiler.addResult(environment.getURI(), this .data);
254: return result;
255: } else {
256: getLogger().warn(
257: "Profiler Data havn't any components to measure");
258: return super .process(environment);
259: }
260: }
261:
262: /**
263: * Process the SAX event pipeline
264: */
265: protected boolean processXMLPipeline(Environment environment)
266: throws ProcessingException {
267: this .index = 0;
268: if (this .data != null) {
269: // Capture environment info
270: this .data.setEnvironmentInfo(new EnvironmentInfo(
271: environment));
272:
273: // Execute pipeline
274: long time = System.currentTimeMillis();
275: boolean result = super .processXMLPipeline(environment);
276:
277: this .data.setTotalTime(System.currentTimeMillis() - time);
278:
279: // Report
280: profiler.addResult(environment.getURI(), this .data);
281: return result;
282: } else {
283: getLogger().warn(
284: "Profiler Data havn't any components to measure");
285: return super .processXMLPipeline(environment);
286: }
287: }
288:
289: /**
290: * Process the pipeline using a reader.
291: */
292: protected boolean processReader(Environment environment)
293: throws ProcessingException {
294: this .index = 0;
295: if (this .data != null) {
296: // Capture environment info
297: this .data.setEnvironmentInfo(new EnvironmentInfo(
298: environment));
299:
300: // Execute pipeline
301: long time = System.currentTimeMillis();
302: boolean result = super .processReader(environment);
303:
304: this .data.setTotalTime(System.currentTimeMillis() - time);
305:
306: // Report
307: profiler.addResult(environment.getURI(), this .data);
308: return result;
309: } else {
310: getLogger().warn(
311: "Profiler Data havn't any components to measure");
312: return super .processReader(environment);
313: }
314: }
315:
316: /**
317: * Connect the next component
318: *
319: * @param environment
320: * @param producer
321: * @param consumer
322: */
323: protected void connect(Environment environment,
324: XMLProducer producer, XMLConsumer consumer)
325: throws ProcessingException {
326: ProfilingXMLPipe connector = new ProfilingXMLPipe();
327:
328: connector.setup(this.index, this.data);
329: this.index++;
330: super.connect(environment, producer, connector);
331: super.connect(environment, connector, consumer);
332: }
333:
334: }
|