blob: d2166f0a2b0d5edb6097c0db20945a30f643f28f [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.cocoon.components;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.cocoon.Processor;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.xml.XMLConsumer;
import org.apache.commons.collections.ArrayStack;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
/**
* The stack for the processing environment.
* This is a special implementation of a stack for the handling of the
* cocoon protocol.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Id$
*/
final class EnvironmentStack extends ArrayStack {
int offset;
int getOffset() {
return this.offset;
}
void setOffset(int value) {
this.offset = value;
}
Item getCurrent() {
return (Item)this.get(offset);
}
public Object clone() {
EnvironmentStack old = (EnvironmentStack) super.clone();
old.offset = offset;
return old;
}
XMLConsumer getEnvironmentAwareConsumerWrapper(XMLConsumer consumer,
int oldOffset) {
return new EnvironmentChanger(consumer, this, oldOffset, this.offset);
}
static final class Item {
public final Environment env;
public final Processor processor;
public final ComponentManager manager;
public final int offset;
public Item(Environment env, Processor processor, ComponentManager manager, int offset) {
this.env = env;
this.processor = processor;
this.manager = manager;
this.offset = offset;
}
}
}
/**
* This class is an {@link XMLConsumer} that changes the current environment.
* When a pipeline calls an internal pipeline, two environments are
* established: one for the calling pipeline and one for the internal pipeline.
* Now, if SAX events are send from the internal pipeline, they are
* received by some component of the calling pipeline, so inbetween we
* have to change the environment forth and back.
*/
final class EnvironmentChanger implements XMLConsumer {
final XMLConsumer consumer;
final EnvironmentStack stack;
final int oldOffset;
final int newOffset;
EnvironmentChanger(XMLConsumer consumer, EnvironmentStack es,
int oldOffset, int newOffset) {
this.consumer = consumer;
this.stack = es;
this.oldOffset = oldOffset;
this.newOffset = newOffset;
}
public void setDocumentLocator(Locator locator) {
this.stack.setOffset(this.oldOffset);
this.consumer.setDocumentLocator(locator);
this.stack.setOffset(this.newOffset);
}
public void startDocument()
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.startDocument();
this.stack.setOffset(this.newOffset);
}
public void endDocument()
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.endDocument();
this.stack.setOffset(this.newOffset);
}
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.startPrefixMapping(prefix, uri);
this.stack.setOffset(this.newOffset);
}
public void endPrefixMapping(String prefix)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.endPrefixMapping(prefix);
this.stack.setOffset(this.newOffset);
}
public void startElement(String uri, String loc, String raw, Attributes a)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.startElement(uri, loc, raw, a);
this.stack.setOffset(this.newOffset);
}
public void endElement(String uri, String loc, String raw)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.endElement(uri, loc, raw);
this.stack.setOffset(this.newOffset);
}
public void characters(char c[], int start, int len)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.characters(c, start, len);
this.stack.setOffset(this.newOffset);
}
public void ignorableWhitespace(char c[], int start, int len)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.ignorableWhitespace(c, start, len);
this.stack.setOffset(this.newOffset);
}
public void processingInstruction(String target, String data)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.processingInstruction(target, data);
this.stack.setOffset(this.newOffset);
}
public void skippedEntity(String name)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.skippedEntity(name);
this.stack.setOffset(this.newOffset);
}
public void startDTD(String name, String publicId, String systemId)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.startDTD(name, publicId, systemId);
this.stack.setOffset(this.newOffset);
}
public void endDTD()
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.endDTD();
this.stack.setOffset(this.newOffset);
}
public void startEntity(String name)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.startEntity(name);
this.stack.setOffset(this.newOffset);
}
public void endEntity(String name)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.endEntity(name);
this.stack.setOffset(this.newOffset);
}
public void startCDATA()
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.startCDATA();
this.stack.setOffset(this.newOffset);
}
public void endCDATA()
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.endCDATA();
this.stack.setOffset(this.newOffset);
}
public void comment(char ch[], int start, int len)
throws SAXException {
this.stack.setOffset(this.oldOffset);
this.consumer.comment(ch, start, len);
this.stack.setOffset(this.newOffset);
}
}