KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > ajax > BrowserUpdateTransformer


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.ajax;
17
18 import java.io.IOException JavaDoc;
19 import java.util.Map JavaDoc;
20
21 import org.apache.avalon.framework.parameters.Parameters;
22 import org.apache.cocoon.ProcessingException;
23 import org.apache.cocoon.environment.ObjectModelHelper;
24 import org.apache.cocoon.environment.Request;
25 import org.apache.cocoon.environment.SourceResolver;
26 import org.apache.cocoon.transformation.AbstractTransformer;
27 import org.apache.cocoon.xml.AttributesImpl;
28 import org.apache.cocoon.xml.RedundantNamespacesFilter;
29 import org.xml.sax.Attributes JavaDoc;
30 import org.xml.sax.Locator JavaDoc;
31 import org.xml.sax.SAXException JavaDoc;
32 import org.xml.sax.SAXParseException JavaDoc;
33
34 /**
35  *
36  * @version $Id: BrowserUpdateTransformer.java 292158 2005-09-28 10:24:51Z sylvain $
37  */

38
39 public class BrowserUpdateTransformer extends AbstractTransformer {
40     
41     public static final String JavaDoc AJAXMODE_PARAM = "cocoon-ajax";
42     
43     public static final String JavaDoc BU_NSURI = "http://apache.org/cocoon/browser-update/1.0";
44     
45     private boolean ajaxRequest = false;
46     
47     private int replaceDepth = 0;
48     
49     private boolean inUpdateTag = false;
50     private String JavaDoc updateTagId = null;
51     
52     Locator JavaDoc locator;
53
54     public void setup(SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc src, Parameters par) throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
55
56         Request request = ObjectModelHelper.getRequest(objectModel);
57         this.ajaxRequest = request.getParameter(AJAXMODE_PARAM) != null;
58     }
59     
60     public void setDocumentLocator(Locator JavaDoc locator) {
61         super.setDocumentLocator(locator);
62         this.locator = locator;
63     }
64
65     public void startDocument() throws SAXException JavaDoc {
66         
67         if (ajaxRequest) {
68             // Add the namespace filter to our own output.
69
// This is needed as flattening bu:* elements can lead to some weird reordering of
70
// namespace declarations...
71
RedundantNamespacesFilter nsPipe = new RedundantNamespacesFilter();
72             if (this.xmlConsumer != null) {
73                 nsPipe.setConsumer(this.xmlConsumer);
74             } else {
75                 nsPipe.setContentHandler(this.contentHandler);
76             }
77             setConsumer(nsPipe);
78         }
79         
80         super.startDocument();
81         if (ajaxRequest) {
82             // Add a root element. The original one is very likely to be stripped
83
super.startPrefixMapping("bu", BU_NSURI);
84             super.startElement(BU_NSURI, "document", "bu:document", new AttributesImpl());
85         }
86     }
87     
88     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri) throws SAXException JavaDoc {
89         // Passthrough if not in ajax mode or if in a bu:replace
90
if (!this.ajaxRequest || this.replaceDepth > 0) {
91             super.startPrefixMapping(prefix, uri);
92         }
93     }
94
95     public void startElement(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw, Attributes JavaDoc attrs) throws SAXException JavaDoc {
96         if (BU_NSURI.equals(uri) && "replace".equals(loc)) {
97             // Keep the id attribute. It may be null, in which case the one of the
98
// child element will be used.
99
this.updateTagId = attrs.getValue("id");
100             this.inUpdateTag = true;
101             if (this.ajaxRequest && this.replaceDepth == 0) {
102                 // Pass this element through
103
super.startElement(uri, loc, raw, attrs);
104             }
105             replaceDepth++;
106         } else {
107             // Passthrough if not in ajax mode or if in a bu:replace
108

109             // Is the enclosing element a bu:replace?
110
if (this.inUpdateTag) {
111                 this.inUpdateTag = false;
112                 // Is there already an id?
113
String JavaDoc localId = attrs.getValue("id");
114                 if (localId != null) {
115                     // Yes: check it's the same
116
if (this.updateTagId != null && !localId.equals(this.updateTagId)) {
117                         throw new SAXParseException JavaDoc("Id on bu:replace (" + this.updateTagId + ") and " + raw + " (" +
118                                 localId + ") don't match.", this.locator);
119                     }
120                 } else {
121                     // No: add it
122
if (this.updateTagId == null) {
123                         throw new SAXParseException JavaDoc("Neither bu:replace nor " + raw + " have an id attribute.", this.locator);
124                     }
125                     AttributesImpl newAttrs = new AttributesImpl(attrs);
126                     newAttrs.addCDATAAttribute("id", this.updateTagId);
127                     attrs = newAttrs;
128                 }
129                 this.updateTagId = null;
130             }
131             if (!this.ajaxRequest || this.replaceDepth > 0) {
132                 super.startElement(uri, loc, raw, attrs);
133             }
134         }
135     }
136
137     public void characters(char[] buffer, int offset, int len) throws SAXException JavaDoc {
138         if (this.inUpdateTag) {
139             // Check that it's only spaces
140
for (int i = offset; i < len; i++) {
141                 if (!Character.isWhitespace(buffer[i])) {
142                     throw new SAXParseException JavaDoc("bu:replace must include a single child element and no text.", this.locator);
143                 }
144             }
145         }
146         if (!this.ajaxRequest || this.replaceDepth > 0) {
147             super.characters(buffer, offset, len);
148         }
149     }
150     
151     public void endElement(String JavaDoc uri, String JavaDoc loc, String JavaDoc raw) throws SAXException JavaDoc {
152         if (BU_NSURI.equals(uri) && "replace".equals(loc)) {
153             replaceDepth--;
154             if (this.ajaxRequest && this.replaceDepth == 0) {
155                 // Pass this element through
156
super.endElement(uri, loc, raw);
157             }
158         } else {
159             // Passthrough if not in ajax mode or if in a bu:replace
160
if (!this.ajaxRequest || this.replaceDepth > 0) {
161                 super.endElement(uri, loc, raw);
162             }
163         }
164     }
165
166     public void endPrefixMapping(String JavaDoc prefix) throws SAXException JavaDoc {
167         // Passthrough if not in ajax mode or if in a bu:replace
168
if (!this.ajaxRequest || this.replaceDepth > 0) {
169             super.endPrefixMapping(prefix);
170         }
171     }
172
173     public void endDocument() throws SAXException JavaDoc {
174         if (ajaxRequest) {
175             super.endElement(BU_NSURI, "document", "bu:document");
176             super.endPrefixMapping("bu");
177         }
178         super.endDocument();
179     }
180 }
181
Popular Tags