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.pipeline.impl;
018:
019: import org.apache.avalon.framework.component.ComponentException;
020: import org.apache.cocoon.ProcessingException;
021: import org.apache.cocoon.caching.CachedResponse;
022: import org.apache.cocoon.caching.CachingOutputStream;
023: import org.apache.cocoon.caching.ComponentCacheKey;
024: import org.apache.cocoon.components.sax.XMLDeserializer;
025: import org.apache.cocoon.components.sax.XMLSerializer;
026: import org.apache.cocoon.components.sax.XMLTeePipe;
027: import org.apache.cocoon.environment.Environment;
028: import org.apache.cocoon.environment.ObjectModelHelper;
029: import org.apache.cocoon.xml.XMLConsumer;
030: import org.apache.cocoon.xml.XMLProducer;
031:
032: import java.io.OutputStream;
033: import java.io.Serializable;
034: import java.util.Iterator;
035:
036: /**
037: * The CachingProcessingPipeline
038: *
039: * @since 2.1
040: * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
041: * @version $Id: CachingProcessingPipeline.java 433543 2006-08-22 06:22:54Z crossley $
042: */
043: public class CachingProcessingPipeline extends
044: AbstractCachingProcessingPipeline {
045:
046: /**
047: * Cache longest cacheable key
048: */
049: protected void cacheResults(Environment environment, OutputStream os)
050: throws Exception {
051: if (this .toCacheKey != null) {
052: // See if there is an expires object for this resource.
053: Long expiresObj = (Long) environment.getObjectModel().get(
054: ObjectModelHelper.EXPIRES_OBJECT);
055:
056: CachedResponse response;
057: if (this .cacheCompleteResponse) {
058: response = new CachedResponse(
059: this .toCacheSourceValidities,
060: ((CachingOutputStream) os).getContent(),
061: expiresObj);
062: response.setContentType(environment.getContentType());
063: } else {
064: response = new CachedResponse(
065: this .toCacheSourceValidities,
066: (byte[]) this .xmlSerializer.getSAXFragment(),
067: expiresObj);
068: }
069:
070: this .cache.store(this .toCacheKey, response);
071: }
072: }
073:
074: /**
075: * Create a new cache key
076: */
077: protected ComponentCacheKey newComponentCacheKey(int type,
078: String role, Serializable key) {
079: return new ComponentCacheKey(type, role, key);
080: }
081:
082: /**
083: * Connect the pipeline.
084: */
085: protected void connectCachingPipeline(Environment environment)
086: throws ProcessingException {
087: try {
088: XMLSerializer localXMLSerializer = null;
089: if (!this .cacheCompleteResponse) {
090: this .xmlSerializer = (XMLSerializer) this .manager
091: .lookup(XMLSerializer.ROLE);
092: localXMLSerializer = this .xmlSerializer;
093: }
094:
095: if (this .cachedResponse == null) {
096: XMLProducer prev = super .generator;
097: XMLConsumer next;
098:
099: int cacheableTransformerCount = this .firstNotCacheableTransformerIndex;
100: Iterator itt = this .transformers.iterator();
101: while (itt.hasNext()) {
102: next = (XMLConsumer) itt.next();
103: if (localXMLSerializer != null) {
104: if (cacheableTransformerCount == 0) {
105: next = new XMLTeePipe(next,
106: localXMLSerializer);
107: localXMLSerializer = null;
108: } else {
109: cacheableTransformerCount--;
110: }
111: }
112: connect(environment, prev, next);
113: prev = (XMLProducer) next;
114: }
115:
116: next = super .lastConsumer;
117: if (localXMLSerializer != null) {
118: next = new XMLTeePipe(next, localXMLSerializer);
119: localXMLSerializer = null;
120: }
121: connect(environment, prev, next);
122:
123: } else {
124: this .xmlDeserializer = (XMLDeserializer) this .manager
125: .lookup(XMLDeserializer.ROLE);
126:
127: // connect the pipeline:
128: XMLProducer prev = xmlDeserializer;
129: XMLConsumer next;
130:
131: int cacheableTransformerCount = 0;
132: Iterator itt = this .transformers.iterator();
133: while (itt.hasNext()) {
134: next = (XMLConsumer) itt.next();
135: if (cacheableTransformerCount >= this .firstProcessedTransformerIndex) {
136: if (localXMLSerializer != null
137: && cacheableTransformerCount == this .firstNotCacheableTransformerIndex) {
138: next = new XMLTeePipe(next,
139: localXMLSerializer);
140: localXMLSerializer = null;
141: }
142: connect(environment, prev, next);
143: prev = (XMLProducer) next;
144: }
145: cacheableTransformerCount++;
146: }
147:
148: next = super .lastConsumer;
149: if (localXMLSerializer != null) {
150: next = new XMLTeePipe(next, localXMLSerializer);
151: localXMLSerializer = null;
152: }
153: connect(environment, prev, next);
154: }
155:
156: } catch (ComponentException e) {
157: throw new ProcessingException(
158: "Could not connect pipeline.", e);
159: }
160: }
161: }
|